2010-01-26 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jan 2010 13:00:15 +0000 (13:00 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jan 2010 13:00:15 +0000 (13:00 +0000)
        Reviewed by Simon Hausmann.

        First steps of the QtScript API.

        Two new classes were created; QScriptEngine and QScriptValue.
        The first should encapsulate a javascript context and the second a script
        value.

        This API is still in development, so it isn't compiled by default.
        To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
        build-webkit.

        https://bugs.webkit.org/show_bug.cgi?id=32565

        * WebKit.pro:
2010-01-26  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>

        Reviewed by Simon Hausmann.

        First steps of the QtScript API.

        Two new classes were created; QScriptEngine and QScriptValue.
        The first should encapsulate a javascript context and the second a script
        value.

        This API is still in development, so it isn't compiled by default.
        To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
        build-webkit.

        https://bugs.webkit.org/show_bug.cgi?id=32565

        * qt/api/QtScript.pro: Added.
        * qt/api/qscriptconverter_p.h: Added.
        (QScriptConverter::toString):
        * qt/api/qscriptengine.cpp: Added.
        (QScriptEngine::QScriptEngine):
        (QScriptEngine::~QScriptEngine):
        (QScriptEngine::evaluate):
        (QScriptEngine::collectGarbage):
        * qt/api/qscriptengine.h: Added.
        * qt/api/qscriptengine_p.cpp: Added.
        (QScriptEnginePrivate::QScriptEnginePrivate):
        (QScriptEnginePrivate::~QScriptEnginePrivate):
        (QScriptEnginePrivate::evaluate):
        * qt/api/qscriptengine_p.h: Added.
        (QScriptEnginePrivate::get):
        (QScriptEnginePrivate::collectGarbage):
        (QScriptEnginePrivate::makeJSValue):
        (QScriptEnginePrivate::context):
        * qt/api/qscriptvalue.cpp: Added.
        (QScriptValue::QScriptValue):
        (QScriptValue::~QScriptValue):
        (QScriptValue::isValid):
        (QScriptValue::isBool):
        (QScriptValue::isBoolean):
        (QScriptValue::isNumber):
        (QScriptValue::isNull):
        (QScriptValue::isString):
        (QScriptValue::isUndefined):
        (QScriptValue::isError):
        (QScriptValue::isObject):
        (QScriptValue::isFunction):
        (QScriptValue::toString):
        (QScriptValue::toNumber):
        (QScriptValue::toBool):
        (QScriptValue::toBoolean):
        (QScriptValue::toInteger):
        (QScriptValue::toInt32):
        (QScriptValue::toUInt32):
        (QScriptValue::toUInt16):
        (QScriptValue::call):
        (QScriptValue::engine):
        (QScriptValue::operator=):
        (QScriptValue::equals):
        (QScriptValue::strictlyEquals):
        * qt/api/qscriptvalue.h: Added.
        (QScriptValue::):
        * qt/api/qscriptvalue_p.h: Added.
        (QScriptValuePrivate::):
        (QScriptValuePrivate::get):
        (QScriptValuePrivate::QScriptValuePrivate):
        (QScriptValuePrivate::isValid):
        (QScriptValuePrivate::isBool):
        (QScriptValuePrivate::isNumber):
        (QScriptValuePrivate::isNull):
        (QScriptValuePrivate::isString):
        (QScriptValuePrivate::isUndefined):
        (QScriptValuePrivate::isError):
        (QScriptValuePrivate::isObject):
        (QScriptValuePrivate::isFunction):
        (QScriptValuePrivate::toString):
        (QScriptValuePrivate::toNumber):
        (QScriptValuePrivate::toBool):
        (QScriptValuePrivate::toInteger):
        (QScriptValuePrivate::toInt32):
        (QScriptValuePrivate::toUInt32):
        (QScriptValuePrivate::toUInt16):
        (QScriptValuePrivate::equals):
        (QScriptValuePrivate::strictlyEquals):
        (QScriptValuePrivate::assignEngine):
        (QScriptValuePrivate::call):
        (QScriptValuePrivate::engine):
        (QScriptValuePrivate::context):
        (QScriptValuePrivate::value):
        (QScriptValuePrivate::object):
        (QScriptValuePrivate::inherits):
        (QScriptValuePrivate::isJSBased):
        (QScriptValuePrivate::isNumberBased):
        (QScriptValuePrivate::isStringBased):
        * qt/api/qtscriptglobal.h: Added.
        * qt/tests/qscriptengine/qscriptengine.pro: Added.
        * qt/tests/qscriptengine/tst_qscriptengine.cpp: Added.
        (tst_QScriptEngine::tst_QScriptEngine):
        (tst_QScriptEngine::~tst_QScriptEngine):
        (tst_QScriptEngine::init):
        (tst_QScriptEngine::cleanup):
        (tst_QScriptEngine::collectGarbage):
        (tst_QScriptEngine::evaluate):
        * qt/tests/qscriptvalue/qscriptvalue.pro: Added.
        * qt/tests/qscriptvalue/tst_qscriptvalue.cpp: Added.
        (tst_QScriptValue::tst_QScriptValue):
        (tst_QScriptValue::~tst_QScriptValue):
        (tst_QScriptValue::init):
        (tst_QScriptValue::cleanup):
        (tst_QScriptValue::ctor):
        (tst_QScriptValue::toString_data):
        (tst_QScriptValue::toString):
        (tst_QScriptValue::copyConstructor_data):
        (tst_QScriptValue::copyConstructor):
        (tst_QScriptValue::assignOperator_data):
        (tst_QScriptValue::assignOperator):
        (tst_QScriptValue::dataSharing):
        (tst_QScriptValue::constructors_data):
        (tst_QScriptValue::constructors):
        (tst_QScriptValue::call):
        * qt/tests/tests.pri: Added.
        * qt/tests/tests.pro: Added.
2010-01-26  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>

        Reviewed by Simon Hausmann.

        First steps of the QtScript API.

        Two new classes were created; QScriptEngine and QScriptValue.
        The first should encapsulate a javascript context and the second a script
        value.

        This API is still in development, so it isn't compiled by default.
        To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
        build-webkit.

        https://bugs.webkit.org/show_bug.cgi?id=32565

        * docs/qtwebkit.qdocconf:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@53850 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
ChangeLog
JavaScriptCore/ChangeLog
JavaScriptCore/qt/api/QtScript.pro [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptconverter_p.h [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptengine.cpp [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptengine.h [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptengine_p.cpp [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptengine_p.h [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptvalue.cpp [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptvalue.h [new file with mode: 0644]
JavaScriptCore/qt/api/qscriptvalue_p.h [new file with mode: 0644]
JavaScriptCore/qt/api/qtscriptglobal.h [new file with mode: 0644]
JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro [new file with mode: 0644]
JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp [new file with mode: 0644]
JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro [new file with mode: 0644]
JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp [new file with mode: 0644]
JavaScriptCore/qt/tests/tests.pri [new file with mode: 0644]
JavaScriptCore/qt/tests/tests.pro [new file with mode: 0644]
WebKit.pro
WebKit/qt/ChangeLog
WebKit/qt/docs/qtwebkit.qdocconf

index 922e54b..d67af57 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2010-01-26  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        First steps of the QtScript API.
+        
+        Two new classes were created; QScriptEngine and QScriptValue.
+        The first should encapsulate a javascript context and the second a script
+        value.
+        
+        This API is still in development, so it isn't compiled by default.
+        To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
+        build-webkit.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32565
+
+        * WebKit.pro:
+
 2010-01-25  Simon Hausmann  <simon.hausmann@nokia.com>
 
         Reviewed by Laszlo Gombos.
index 9f43d7e..94b37c8 100644 (file)
@@ -1,3 +1,126 @@
+2010-01-26  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        First steps of the QtScript API.
+        
+        Two new classes were created; QScriptEngine and QScriptValue.
+        The first should encapsulate a javascript context and the second a script
+        value.
+        
+        This API is still in development, so it isn't compiled by default.
+        To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
+        build-webkit.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32565
+
+        * qt/api/QtScript.pro: Added.
+        * qt/api/qscriptconverter_p.h: Added.
+        (QScriptConverter::toString):
+        * qt/api/qscriptengine.cpp: Added.
+        (QScriptEngine::QScriptEngine):
+        (QScriptEngine::~QScriptEngine):
+        (QScriptEngine::evaluate):
+        (QScriptEngine::collectGarbage):
+        * qt/api/qscriptengine.h: Added.
+        * qt/api/qscriptengine_p.cpp: Added.
+        (QScriptEnginePrivate::QScriptEnginePrivate):
+        (QScriptEnginePrivate::~QScriptEnginePrivate):
+        (QScriptEnginePrivate::evaluate):
+        * qt/api/qscriptengine_p.h: Added.
+        (QScriptEnginePrivate::get):
+        (QScriptEnginePrivate::collectGarbage):
+        (QScriptEnginePrivate::makeJSValue):
+        (QScriptEnginePrivate::context):
+        * qt/api/qscriptvalue.cpp: Added.
+        (QScriptValue::QScriptValue):
+        (QScriptValue::~QScriptValue):
+        (QScriptValue::isValid):
+        (QScriptValue::isBool):
+        (QScriptValue::isBoolean):
+        (QScriptValue::isNumber):
+        (QScriptValue::isNull):
+        (QScriptValue::isString):
+        (QScriptValue::isUndefined):
+        (QScriptValue::isError):
+        (QScriptValue::isObject):
+        (QScriptValue::isFunction):
+        (QScriptValue::toString):
+        (QScriptValue::toNumber):
+        (QScriptValue::toBool):
+        (QScriptValue::toBoolean):
+        (QScriptValue::toInteger):
+        (QScriptValue::toInt32):
+        (QScriptValue::toUInt32):
+        (QScriptValue::toUInt16):
+        (QScriptValue::call):
+        (QScriptValue::engine):
+        (QScriptValue::operator=):
+        (QScriptValue::equals):
+        (QScriptValue::strictlyEquals):
+        * qt/api/qscriptvalue.h: Added.
+        (QScriptValue::):
+        * qt/api/qscriptvalue_p.h: Added.
+        (QScriptValuePrivate::):
+        (QScriptValuePrivate::get):
+        (QScriptValuePrivate::QScriptValuePrivate):
+        (QScriptValuePrivate::isValid):
+        (QScriptValuePrivate::isBool):
+        (QScriptValuePrivate::isNumber):
+        (QScriptValuePrivate::isNull):
+        (QScriptValuePrivate::isString):
+        (QScriptValuePrivate::isUndefined):
+        (QScriptValuePrivate::isError):
+        (QScriptValuePrivate::isObject):
+        (QScriptValuePrivate::isFunction):
+        (QScriptValuePrivate::toString):
+        (QScriptValuePrivate::toNumber):
+        (QScriptValuePrivate::toBool):
+        (QScriptValuePrivate::toInteger):
+        (QScriptValuePrivate::toInt32):
+        (QScriptValuePrivate::toUInt32):
+        (QScriptValuePrivate::toUInt16):
+        (QScriptValuePrivate::equals):
+        (QScriptValuePrivate::strictlyEquals):
+        (QScriptValuePrivate::assignEngine):
+        (QScriptValuePrivate::call):
+        (QScriptValuePrivate::engine):
+        (QScriptValuePrivate::context):
+        (QScriptValuePrivate::value):
+        (QScriptValuePrivate::object):
+        (QScriptValuePrivate::inherits):
+        (QScriptValuePrivate::isJSBased):
+        (QScriptValuePrivate::isNumberBased):
+        (QScriptValuePrivate::isStringBased):
+        * qt/api/qtscriptglobal.h: Added.
+        * qt/tests/qscriptengine/qscriptengine.pro: Added.
+        * qt/tests/qscriptengine/tst_qscriptengine.cpp: Added.
+        (tst_QScriptEngine::tst_QScriptEngine):
+        (tst_QScriptEngine::~tst_QScriptEngine):
+        (tst_QScriptEngine::init):
+        (tst_QScriptEngine::cleanup):
+        (tst_QScriptEngine::collectGarbage):
+        (tst_QScriptEngine::evaluate):
+        * qt/tests/qscriptvalue/qscriptvalue.pro: Added.
+        * qt/tests/qscriptvalue/tst_qscriptvalue.cpp: Added.
+        (tst_QScriptValue::tst_QScriptValue):
+        (tst_QScriptValue::~tst_QScriptValue):
+        (tst_QScriptValue::init):
+        (tst_QScriptValue::cleanup):
+        (tst_QScriptValue::ctor):
+        (tst_QScriptValue::toString_data):
+        (tst_QScriptValue::toString):
+        (tst_QScriptValue::copyConstructor_data):
+        (tst_QScriptValue::copyConstructor):
+        (tst_QScriptValue::assignOperator_data):
+        (tst_QScriptValue::assignOperator):
+        (tst_QScriptValue::dataSharing):
+        (tst_QScriptValue::constructors_data):
+        (tst_QScriptValue::constructors):
+        (tst_QScriptValue::call):
+        * qt/tests/tests.pri: Added.
+        * qt/tests/tests.pro: Added.
+
 2010-01-25  Dmitry Titov  <dimich@chromium.org>
 
         Reviewed by David Levin.
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro
new file mode 100644 (file)
index 0000000..c5e253d
--- /dev/null
@@ -0,0 +1,37 @@
+TARGET     = QtScript
+TEMPLATE   = lib
+QT         = core
+
+INCLUDEPATH += $$PWD
+
+CONFIG += building-libs
+JAVASCRIPTCORE_JIT = yes
+
+isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = ../../generated
+CONFIG(debug, debug|release) {
+    OBJECTS_DIR = obj/debug
+} else { # Release
+    OBJECTS_DIR = obj/release
+}
+
+include($$PWD/../../../WebKit.pri)
+include($$PWD/../../JavaScriptCore.pri)
+
+INCLUDEPATH += $$PWD/../../API
+
+SOURCES +=  $$PWD/qscriptengine.cpp \
+            $$PWD/qscriptengine_p.cpp \
+            $$PWD/qscriptvalue.cpp \
+
+HEADERS +=  $$PWD/qtscriptglobal.h \
+            $$PWD/qscriptengine.h \
+            $$PWD/qscriptengine_p.h \
+            $$PWD/qscriptvalue.h \
+            $$PWD/qscriptvalue_p.h \
+            $$PWD/qscriptconverter_p.h \
+
+
+!static: DEFINES += QT_MAKEDLL
+
+DESTDIR = $$OUTPUT_DIR/lib
+
diff --git a/JavaScriptCore/qt/api/qscriptconverter_p.h b/JavaScriptCore/qt/api/qscriptconverter_p.h
new file mode 100644 (file)
index 0000000..c3ca41f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+    Copyright (C) 2008 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.
+*/
+
+#ifndef qscriptconverter_p_h
+#define qscriptconverter_p_h
+
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qstring.h>
+
+/*
+  \internal
+  \class QScriptConverter
+  QScriptValue and QScriptEngine helper class. This class's responsibility is to convert values
+  between JS values and Qt/C++ values.
+
+  This is a nice way to inline these functions in both QScriptValue and QScriptEngine.
+*/
+class QScriptConverter {
+public:
+    static QString toString(const JSStringRef str)
+    {
+        return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(str)), JSStringGetLength(str));
+    }
+    static JSStringRef toString(const QString& str)
+    {
+        return JSStringCreateWithUTF8CString(str.toUtf8().constData());
+    }
+    static JSStringRef toString(const char* str)
+    {
+        return JSStringCreateWithUTF8CString(str);
+    }
+};
+
+#endif // qscriptconverter_p_h
diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp
new file mode 100644 (file)
index 0000000..f12f410
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+    Copyright (C) 2009 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 "config.h"
+
+#include "qscriptengine.h"
+
+#include "qscriptengine_p.h"
+#include "qscriptvalue_p.h"
+
+/*!
+    Constructs a QScriptEngine object.
+
+    The globalObject() is initialized to have properties as described in ECMA-262, Section 15.1.
+*/
+QScriptEngine::QScriptEngine()
+    : d_ptr(new QScriptEnginePrivate(this))
+{
+}
+
+/*!
+    Destroys this QScriptEngine.
+*/
+QScriptEngine::~QScriptEngine()
+{
+}
+
+/*!
+    Evaluates \a program, using \a lineNumber as the base line number,
+    and returns the result of the evaluation.
+
+    The script code will be evaluated in the current context.
+
+    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().
+
+    \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.
+
+    \a fileName is used for error reporting. For example in error objects
+    the file name is accessible through the "fileName" property if it's
+    provided with this function.
+*/
+QScriptValue QScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
+{
+    return QScriptValuePrivate::get(d_ptr->evaluate(program, fileName, lineNumber));
+}
+
+/*!
+    Runs the garbage collector.
+
+    The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
+    no longer reachable in the script environment.
+
+    Normally you don't need to call this function; the garbage collector will automatically be invoked
+    when the QScriptEngine decides that it's wise to do so (i.e. when a certain number of new objects
+    have been created). However, you can call this function to explicitly request that garbage
+    collection should be performed as soon as possible.
+*/
+void QScriptEngine::collectGarbage()
+{
+    d_ptr->collectGarbage();
+}
diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h
new file mode 100644 (file)
index 0000000..cf61d35
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    Copyright (C) 2009 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.
+*/
+
+#ifndef qscriptengine_h
+#define qscriptengine_h
+
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QScriptValue;
+class QScriptEnginePrivate;
+
+// Internal typedef
+typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr;
+
+class QScriptEngine : public QObject {
+public:
+    QScriptEngine();
+    ~QScriptEngine();
+
+    QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
+    void collectGarbage();
+
+private:
+    friend class QScriptEnginePrivate;
+
+    QScriptEnginePtr d_ptr;
+};
+
+#endif
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
new file mode 100644 (file)
index 0000000..de8a355
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright (C) 2009 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 "config.h"
+
+#include "qscriptengine_p.h"
+
+#include "qscriptvalue_p.h"
+
+/*!
+    Constructs a default QScriptEnginePrivate object, a new global context will be created.
+    \internal
+*/
+QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine)
+    : q_ptr(const_cast<QScriptEngine*>(engine))
+    , m_context(JSGlobalContextCreate(0))
+{
+}
+
+QScriptEnginePrivate::~QScriptEnginePrivate()
+{
+    JSGlobalContextRelease(m_context);
+}
+
+/*!
+    Evaluates program and returns the result of the evaluation.
+    \internal
+*/
+QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QString& program, const QString& fileName, int lineNumber)
+{
+    JSStringRef script = QScriptConverter::toString(program);
+    JSStringRef file = QScriptConverter::toString(fileName);
+    JSValueRef exception;
+    JSValueRef result = JSEvaluateScript(m_context, script, /* Global Object */ 0, file, lineNumber, &exception);
+    if (!result)
+        return new QScriptValuePrivate(this, exception); // returns an exception
+    return new QScriptValuePrivate(this, result);
+}
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h
new file mode 100644 (file)
index 0000000..8e27c42
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+    Copyright (C) 2009 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.
+*/
+
+#ifndef qscriptengine_p_h
+#define qscriptengine_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptengine.h"
+#include "qscriptvalue.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QScriptEngine;
+
+class QScriptEnginePrivate : public QSharedData {
+public:
+    static QScriptEnginePtr get(const QScriptEngine* q) { Q_ASSERT(q); return q->d_ptr; }
+    static QScriptEngine* get(const QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_ptr; }
+
+    QScriptEnginePrivate(const QScriptEngine*);
+    ~QScriptEnginePrivate();
+
+    QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber);
+    inline void collectGarbage();
+
+    inline JSValueRef makeJSValue(double number) const;
+    inline JSValueRef makeJSValue(int number) const;
+    inline JSValueRef makeJSValue(uint number) const;
+    inline JSValueRef makeJSValue(const QString& string) const;
+    inline JSValueRef makeJSValue(bool number) const;
+    inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const;
+
+    inline JSGlobalContextRef context() const;
+private:
+    QScriptEngine* q_ptr;
+    JSGlobalContextRef m_context;
+};
+
+void QScriptEnginePrivate::collectGarbage()
+{
+    JSGarbageCollect(m_context);
+}
+
+JSValueRef QScriptEnginePrivate::makeJSValue(double number) const
+{
+    return JSValueMakeNumber(m_context, number);
+}
+
+JSValueRef QScriptEnginePrivate::makeJSValue(int number) const
+{
+    return JSValueMakeNumber(m_context, number);
+}
+
+JSValueRef QScriptEnginePrivate::makeJSValue(uint number) const
+{
+    return JSValueMakeNumber(m_context, number);
+}
+
+JSValueRef QScriptEnginePrivate::makeJSValue(const QString& string) const
+{
+    return JSValueMakeString(m_context, QScriptConverter::toString(string));
+}
+
+JSValueRef QScriptEnginePrivate::makeJSValue(bool value) const
+{
+    return JSValueMakeBoolean(m_context, value);
+}
+
+JSValueRef QScriptEnginePrivate::makeJSValue(QScriptValue::SpecialValue value) const
+{
+    if (value == QScriptValue::NullValue)
+        return JSValueMakeNull(m_context);
+    return JSValueMakeUndefined(m_context);
+}
+
+JSGlobalContextRef QScriptEnginePrivate::context() const
+{
+    return m_context;
+}
+
+#endif
diff --git a/JavaScriptCore/qt/api/qscriptvalue.cpp b/JavaScriptCore/qt/api/qscriptvalue.cpp
new file mode 100644 (file)
index 0000000..127fe04
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+    Copyright (C) 2009 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 "config.h"
+
+#include "qscriptvalue.h"
+
+#include "qscriptengine.h"
+#include "qscriptengine_p.h"
+#include "qscriptvalue_p.h"
+#include <QtCore/qdebug.h>
+
+/*!
+    Constructs an invalid value.
+*/
+QScriptValue::QScriptValue()
+    : d_ptr(new QScriptValuePrivate())
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a boolean \a value.
+*/
+QScriptValue::QScriptValue(bool value)
+    : d_ptr(new QScriptValuePrivate(value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a number \a value.
+*/
+QScriptValue::QScriptValue(int value)
+    : d_ptr(new QScriptValuePrivate(value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a number \a value.
+*/
+QScriptValue::QScriptValue(uint value)
+    : d_ptr(new QScriptValuePrivate(value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a number \a value.
+*/
+QScriptValue::QScriptValue(qsreal value)
+    : d_ptr(new QScriptValuePrivate(value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a string \a value.
+*/
+QScriptValue::QScriptValue(const QString& value)
+    : d_ptr(new QScriptValuePrivate(value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a special \a value.
+*/
+QScriptValue::QScriptValue(SpecialValue value)
+    : d_ptr(new QScriptValuePrivate(value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue with a string \a value.
+*/
+QScriptValue::QScriptValue(const char* value)
+    : d_ptr(new QScriptValuePrivate(QString::fromUtf8(value)))
+{
+}
+
+/*!
+    Block automatic convertion to bool
+    \internal
+*/
+QScriptValue::QScriptValue(void* d)
+{
+    Q_ASSERT(false);
+}
+
+/*!
+    Constructs a new QScriptValue from private
+    \internal
+*/
+QScriptValue::QScriptValue(QScriptValuePrivate* d)
+    : d_ptr(d)
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the boolean \a value and
+  registers it with the script \a engine.
+*/
+QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
+    : d_ptr(new QScriptValuePrivate(engine, value))
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the integer \a value and
+  registers it with the script \a engine.
+*/
+QScriptValue::QScriptValue(QScriptEngine* engine, int value)
+    : d_ptr(new QScriptValuePrivate(engine, value))
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the unsigned integer \a value and
+  registers it with the script \a engine.
+ */
+QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
+    : d_ptr(new QScriptValuePrivate(engine, value))
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the qsreal \a value and
+  registers it with the script \a engine.
+*/
+QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
+    : d_ptr(new QScriptValuePrivate(engine, value))
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the string \a value and
+  registers it with the script \a engine.
+*/
+QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
+    : d_ptr(new QScriptValuePrivate(engine, value))
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the string \a value and
+  registers it with the script \a engine.
+*/
+QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
+    : d_ptr(new QScriptValuePrivate(engine, QString::fromUtf8(value)))
+{
+}
+
+/*!
+  \obsolete
+
+  Constructs a new QScriptValue with the special \a value and
+  registers it with the script \a engine.
+*/
+QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value)
+    : d_ptr(new QScriptValuePrivate(engine, value))
+{
+}
+
+/*!
+  Constructs a new QScriptValue that is a copy of \a other.
+
+  Note that if \a other is an object (i.e., isObject() would return
+  true), then only a reference to the underlying object is copied into
+  the new script value (i.e., the object itself is not copied).
+*/
+QScriptValue::QScriptValue(const QScriptValue& other)
+    : d_ptr(other.d_ptr)
+{
+}
+
+/*!
+    Destroys this QScriptValue.
+*/
+QScriptValue::~QScriptValue()
+{
+}
+
+/*!
+  Returns true if this QScriptValue is valid; otherwise returns
+  false.
+*/
+bool QScriptValue::isValid() const
+{
+    return d_ptr->isValid();
+}
+
+/*!
+  Returns true if this QScriptValue is of the primitive type Boolean;
+  otherwise returns false.
+
+  \sa toBool()
+*/
+bool QScriptValue::isBool() const
+{
+    return d_ptr->isBool();
+}
+
+/*!
+  \obsolete
+
+  Use isBool() instead.
+  Returns true if this QScriptValue is of the primitive type Boolean;
+  otherwise returns false.
+*/
+bool QScriptValue::isBoolean() const
+{
+    return d_ptr->isBool();
+}
+
+/*!
+  Returns true if this QScriptValue is of the primitive type Number;
+  otherwise returns false.
+
+  \sa toNumber()
+*/
+bool QScriptValue::isNumber() const
+{
+    return d_ptr->isNumber();
+}
+
+/*!
+  Returns true if this QScriptValue is of the primitive type Null;
+  otherwise returns false.
+
+  \sa QScriptEngine::nullValue()
+*/
+bool QScriptValue::isNull() const
+{
+    return d_ptr->isNull();
+}
+
+/*!
+  Returns true if this QScriptValue is of the primitive type String;
+  otherwise returns false.
+
+  \sa toString()
+*/
+bool QScriptValue::isString() const
+{
+    return d_ptr->isString();
+}
+
+/*!
+  Returns true if this QScriptValue is of the primitive type Undefined;
+  otherwise returns false.
+
+  \sa QScriptEngine::undefinedValue()
+*/
+bool QScriptValue::isUndefined() const
+{
+    return d_ptr->isUndefined();
+}
+
+/*!
+  Returns true if this QScriptValue is an object of the Error class;
+  otherwise returns false.
+
+  \sa QScriptContext::throwError()
+*/
+bool QScriptValue::isError() const
+{
+    return d_ptr->isError();
+}
+
+/*!
+  Returns true if this QScriptValue is of the Object type; otherwise
+  returns false.
+
+  Note that function values, variant values, and QObject values are
+  objects, so this function returns true for such values.
+
+  \sa toObject(), QScriptEngine::newObject()
+*/
+bool QScriptValue::isObject() const
+{
+    return d_ptr->isObject();
+}
+
+/*!
+  Returns true if this QScriptValue is a function; otherwise returns
+  false.
+
+  \sa call()
+*/
+bool QScriptValue::isFunction() const
+{
+    return d_ptr->isFunction();
+}
+
+/*!
+  Returns the string value of this QScriptValue, as defined in
+  \l{ECMA-262} section 9.8, "ToString".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's toString() function (and possibly valueOf()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa isString()
+*/
+QString QScriptValue::toString() const
+{
+    return d_ptr->toString();
+}
+
+/*!
+  Returns the number value of this QScriptValue, as defined in
+  \l{ECMA-262} section 9.3, "ToNumber".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's valueOf() function (and possibly toString()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16()
+*/
+qsreal QScriptValue::toNumber() const
+{
+    return d_ptr->toNumber();
+}
+
+/*!
+  Returns the boolean value of this QScriptValue, using the conversion
+  rules described in \l{ECMA-262} section 9.2, "ToBoolean".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's valueOf() function (and possibly toString()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa isBool()
+*/
+bool QScriptValue::toBool() const
+{
+    return d_ptr->toBool();
+}
+
+/*!
+  \obsolete
+
+  Use toBool() instead.
+*/
+bool QScriptValue::toBoolean() const
+{
+    return d_ptr->toBool();
+}
+
+/*!
+  Returns the integer value of this QScriptValue, using the conversion
+  rules described in \l{ECMA-262} section 9.4, "ToInteger".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's valueOf() function (and possibly toString()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa toNumber()
+*/
+qsreal QScriptValue::toInteger() const
+{
+    return d_ptr->toInteger();
+}
+
+/*!
+  Returns the signed 32-bit integer value of this QScriptValue, using
+  the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's valueOf() function (and possibly toString()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa toNumber(), toUInt32()
+*/
+qint32 QScriptValue::toInt32() const
+{
+    return d_ptr->toInt32();
+}
+
+/*!
+  Returns the unsigned 32-bit integer value of this QScriptValue, using
+  the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's valueOf() function (and possibly toString()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa toNumber(), toInt32()
+*/
+quint32 QScriptValue::toUInt32() const
+{
+    return d_ptr->toUInt32();
+}
+
+/*!
+  Returns the unsigned 16-bit integer value of this QScriptValue, using
+  the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16".
+
+  Note that if this QScriptValue is an object, calling this function
+  has side effects on the script engine, since the engine will call
+  the object's valueOf() function (and possibly toString()) in an
+  attempt to convert the object to a primitive value (possibly
+  resulting in an uncaught script exception).
+
+  \sa toNumber()
+*/
+quint16 QScriptValue::toUInt16() const
+{
+    return d_ptr->toUInt16();
+}
+
+/*!
+  Calls this QScriptValue as a function, using \a thisObject as
+  the `this' object in the function call, and passing \a args
+  as arguments to the function. Returns the value returned from
+  the function.
+
+  If this QScriptValue is not a function, call() does nothing
+  and returns an invalid QScriptValue.
+
+  Note that if \a thisObject is not an object, the global object
+  (see \l{QScriptEngine::globalObject()}) will be used as the
+  `this' object.
+
+  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
+  QScriptEngine::hasUncaughtException() to determine if an exception
+  occurred.
+
+  \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2
+
+  \sa construct()
+*/
+QScriptValue QScriptValue::call(const QScriptValue& thisObject, const QScriptValueList& args)
+{
+    return d_ptr->call(thisObject.d_ptr.data(), args);
+}
+
+/*!
+  Returns the QScriptEngine that created this QScriptValue,
+  or 0 if this QScriptValue is invalid or the value is not
+  associated with a particular engine.
+*/
+QScriptEngine* QScriptValue::engine() const
+{
+    QScriptEnginePrivate* engine = d_ptr->engine();
+    if (engine)
+        return QScriptEnginePrivate::get(engine);
+    return 0;
+}
+
+/*!
+  Assigns the \a other value to this QScriptValue.
+
+  Note that if \a other is an object (isObject() returns true),
+  only a reference to the underlying object will be assigned;
+  the object itself will not be copied.
+*/
+QScriptValue& QScriptValue::operator=(const QScriptValue& other)
+{
+    d_ptr = other.d_ptr;
+    return *this;
+}
+
+/*!
+  Returns true if this QScriptValue is equal to \a other, otherwise
+  returns false. The comparison follows the behavior described in
+  \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
+  Algorithm".
+
+  This function can return true even if the type of this QScriptValue
+  is different from the type of the \a other value; i.e. the
+  comparison is not strict.  For example, comparing the number 9 to
+  the string "9" returns true; comparing an undefined value to a null
+  value returns true; comparing a \c{Number} object whose primitive
+  value is 6 to a \c{String} object whose primitive value is "6"
+  returns true; and comparing the number 1 to the boolean value
+  \c{true} returns true. If you want to perform a comparison
+  without such implicit value conversion, use strictlyEquals().
+
+  Note that if this QScriptValue or the \a other value are objects,
+  calling this function has side effects on the script engine, since
+  the engine will call the object's valueOf() function (and possibly
+  toString()) in an attempt to convert the object to a primitive value
+  (possibly resulting in an uncaught script exception).
+
+  \sa strictlyEquals(), lessThan()
+*/
+bool QScriptValue::equals(const QScriptValue& other) const
+{
+    return d_ptr == other.d_ptr || d_ptr->equals(QScriptValuePrivate::get(other));
+}
+
+/*!
+  Returns true if this QScriptValue is equal to \a other using strict
+  comparison (no conversion), otherwise returns false. The comparison
+  follows the behavior described in \l{ECMA-262} section 11.9.6, "The
+  Strict Equality Comparison Algorithm".
+
+  If the type of this QScriptValue is different from the type of the
+  \a other value, this function returns false. If the types are equal,
+  the result depends on the type, as shown in the following table:
+
+    \table
+    \header \o Type \o Result
+    \row    \o Undefined  \o true
+    \row    \o Null       \o true
+    \row    \o Boolean    \o true if both values are true, false otherwise
+    \row    \o Number     \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
+    \row    \o String     \o true if both values are exactly the same sequence of characters, false otherwise
+    \row    \o Object     \o true if both values refer to the same object, false otherwise
+    \endtable
+
+  \sa equals()
+*/
+bool QScriptValue::strictlyEquals(const QScriptValue& other) const
+{
+    return d_ptr == other.d_ptr || d_ptr->strictlyEquals(QScriptValuePrivate::get(other));
+}
diff --git a/JavaScriptCore/qt/api/qscriptvalue.h b/JavaScriptCore/qt/api/qscriptvalue.h
new file mode 100644 (file)
index 0000000..d45aed3
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+    Copyright (C) 2009 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.
+*/
+
+#ifndef qscriptvalue_h
+#define qscriptvalue_h
+
+#include <QtCore/qlist.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptEngine;
+class QScriptValuePrivate;
+
+class QScriptValue;
+typedef QList<QScriptValue> QScriptValueList;
+
+typedef double qsreal;
+
+class QScriptValue {
+public:    
+    enum SpecialValue {
+        NullValue,
+        UndefinedValue
+    };
+
+    QScriptValue();
+    QScriptValue(bool value);
+    QScriptValue(int value);
+    QScriptValue(uint value);
+    QScriptValue(qsreal value);
+    QScriptValue(const QString& value);
+    QScriptValue(const char* value);
+    QScriptValue(SpecialValue value);
+    QScriptValue(const QScriptValue& other);
+
+    QScriptValue(QScriptEngine* engine, bool value);
+    QScriptValue(QScriptEngine* engine, int value);
+    QScriptValue(QScriptEngine* engine, uint value);
+    QScriptValue(QScriptEngine* engine, qsreal value);
+    QScriptValue(QScriptEngine* engine, const QString& value);
+    QScriptValue(QScriptEngine* engine, const char* value);
+    QScriptValue(QScriptEngine* engine, SpecialValue value);
+
+    ~QScriptValue();
+
+    QScriptValue& operator=(const QScriptValue& other);
+    bool equals(const QScriptValue& other) const;
+    bool strictlyEquals(const QScriptValue& other) const;
+
+    QScriptEngine* engine() const;
+
+    bool isValid() const;
+    bool isBool() const;
+    bool isBoolean() const;
+    bool isNumber() const;
+    bool isFunction() const;
+    bool isNull() const;
+    bool isString() const;
+    bool isUndefined() const;
+    bool isObject() const;
+    bool isError() const;
+
+    QString toString() const;
+    qsreal toNumber() const;
+    bool toBool() const;
+    bool toBoolean() const;
+    qsreal toInteger() const;
+    qint32 toInt32() const;
+    quint32 toUInt32() const;
+    quint16 toUInt16() const;
+
+    QScriptValue call(const QScriptValue& thisObject = QScriptValue(),
+                      const QScriptValueList& args = QScriptValueList());
+
+private:
+    QScriptValue(void*);
+    QScriptValue(QScriptValuePrivate*);
+
+    QExplicitlySharedDataPointer<QScriptValuePrivate> d_ptr;
+
+    friend class QScriptValuePrivate;
+};
+
+#endif // qscriptvalue_h
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
new file mode 100644 (file)
index 0000000..dcd36ce
--- /dev/null
@@ -0,0 +1,718 @@
+/*
+    Copyright (C) 2008 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.
+*/
+
+#ifndef qscriptvalue_p_h
+#define qscriptvalue_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptengine_p.h"
+#include "qscriptvalue.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptEngine;
+class QScriptValue;
+
+/*
+  \internal
+  \class QScriptValuePrivate
+
+  Implementation of QScriptValue.
+  The implementation is based on a state machine. The states names are included in
+  QScriptValuePrivate::States. Each method should check for the current state and then perform a
+  correct action.
+
+  States:
+    Invalid -> QSVP is invalid, no assumptions should be made about class members (apart from m_value).
+    CString -> QSVP is created from QString or const char* and no JSC engine has been associated yet.
+        Current value is kept in m_string,
+    CNumber -> QSVP is created from int, uint, double... and no JSC engine has been bind yet. Current
+        value is kept in m_number
+    CBool -> QSVP is created from bool and no JSC engine has been associated yet. Current value is kept
+        in m_number
+    CSpecial -> QSVP is Undefined or Null, but a JSC engine hasn't been associated yet, current value
+        is kept in m_number (cast of QScriptValue::SpecialValue)
+    JSValue -> QSVP is associated with engine, but there is no information about real type, the state
+        have really short live cycle. Normally it is created as a function call result.
+    JSNative -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object.
+    JSObject -> QSVP is associated with engine, and it is sure that it is a JavaScript object.
+
+  Each state keep all necessary information to invoke all methods, if not it should be changed to
+  a proper state. Changed state shouldn't be reverted.
+*/
+
+class QScriptValuePrivate : public QSharedData {
+public:
+    inline static QScriptValuePrivate* get(const QScriptValue& q);
+    inline static QScriptValue get(const QScriptValuePrivate* d);
+    inline static QScriptValue get(QScriptValuePrivate* d);
+
+    inline ~QScriptValuePrivate();
+
+    inline QScriptValuePrivate();
+    inline QScriptValuePrivate(const QString& string);
+    inline QScriptValuePrivate(bool value);
+    inline QScriptValuePrivate(int number);
+    inline QScriptValuePrivate(uint number);
+    inline QScriptValuePrivate(qsreal number);
+    inline QScriptValuePrivate(QScriptValue::SpecialValue value);
+
+    inline QScriptValuePrivate(const QScriptEngine* engine, bool value);
+    inline QScriptValuePrivate(const QScriptEngine* engine, int value);
+    inline QScriptValuePrivate(const QScriptEngine* engine, uint value);
+    inline QScriptValuePrivate(const QScriptEngine* engine, qsreal value);
+    inline QScriptValuePrivate(const QScriptEngine* engine, const QString& value);
+    inline QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value);
+
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object);
+
+    inline bool isValid() const;
+    inline bool isBool();
+    inline bool isNumber();
+    inline bool isNull();
+    inline bool isString();
+    inline bool isUndefined();
+    inline bool isError();
+    inline bool isObject();
+    inline bool isFunction();
+
+    inline QString toString() const;
+    inline qsreal toNumber() const;
+    inline bool toBool() const;
+    inline qsreal toInteger() const;
+    inline qint32 toInt32() const;
+    inline quint32 toUInt32() const;
+    inline quint16 toUInt16() const;
+
+    inline bool equals(QScriptValuePrivate* other);
+    inline bool strictlyEquals(const QScriptValuePrivate* other) const;
+    inline bool assignEngine(QScriptEnginePrivate* engine);
+
+    inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args);
+
+    inline JSGlobalContextRef context() const;
+    inline JSValueRef value() const;
+    inline JSObjectRef object() const;
+    inline QScriptEnginePrivate* engine() const;
+
+private:
+    // Please, update class documentation when you change the enum.
+    enum States {
+        Invalid = 0,
+        CString = 0x1000,
+        CNumber,
+        CBool,
+        CSpecial,
+        JSValue = 0x2000, // JS values are equal or higher then this value.
+        JSNative,
+        JSObject
+    } m_state;
+    QScriptEnginePtr m_engine;
+    QString m_string;
+    qsreal m_number;
+    JSValueRef m_value;
+    JSObjectRef m_object;
+
+    inline void setValue(JSValueRef);
+
+    inline bool inherits(const char*);
+
+    inline bool isJSBased() const;
+    inline bool isNumberBased() const;
+    inline bool isStringBased() const;
+};
+
+QScriptValuePrivate* QScriptValuePrivate::get(const QScriptValue& q) { return q.d_ptr.data(); }
+
+QScriptValue QScriptValuePrivate::get(const QScriptValuePrivate* d)
+{
+    return QScriptValue(const_cast<QScriptValuePrivate*>(d));
+}
+
+QScriptValue QScriptValuePrivate::get(QScriptValuePrivate* d)
+{
+    return QScriptValue(d);
+}
+
+QScriptValuePrivate::~QScriptValuePrivate()
+{
+    if (m_value)
+        JSValueUnprotect(context(), m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate()
+    : m_state(Invalid)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QString& string)
+    : m_state(CString)
+    , m_string(string)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(bool value)
+    : m_state(CBool)
+    , m_number(value)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(int number)
+    : m_state(CNumber)
+    , m_number(number)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(uint number)
+    : m_state(CNumber)
+    , m_number(number)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(qsreal number)
+    : m_state(CNumber)
+    , m_number(number)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value)
+    : m_state(CSpecial)
+    , m_number(value)
+    , m_value(0)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value)
+    : m_state(JSNative)
+{
+    if (!engine) {
+        // slower path reinitialization
+        m_state = CBool;
+        m_number = value;
+        m_value = 0;
+    } else {
+        m_engine = QScriptEnginePrivate::get(engine);
+        m_value = m_engine->makeJSValue(value);
+        JSValueProtect(context(), m_value);
+    }
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value)
+    : m_state(JSNative)
+{
+    if (!engine) {
+        // slower path reinitialization
+        m_state = CNumber;
+        m_number = value;
+        m_value = 0;
+    } else {
+        m_engine = QScriptEnginePrivate::get(engine);
+        m_value = m_engine->makeJSValue(value);
+        JSValueProtect(context(), m_value);
+    }
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value)
+    : m_state(JSNative)
+{
+    if (!engine) {
+        // slower path reinitialization
+        m_state = CNumber;
+        m_number = value;
+        m_value = 0;
+    } else {
+        m_engine = QScriptEnginePrivate::get(engine);
+        m_value = m_engine->makeJSValue(value);
+        JSValueProtect(context(), m_value);
+    }
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal value)
+    : m_state(JSNative)
+{
+    if (!engine) {
+        // slower path reinitialization
+        m_state = CNumber;
+        m_number = value;
+        m_value = 0;
+    } else {
+        m_engine = QScriptEnginePrivate::get(engine);
+        m_value = m_engine->makeJSValue(value);
+        JSValueProtect(context(), m_value);
+    }
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QString& value)
+    : m_state(JSNative)
+{
+    if (!engine) {
+        // slower path reinitialization
+        m_state = CString;
+        m_string = value;
+        m_value = 0;
+    } else {
+        m_engine = QScriptEnginePrivate::get(engine);
+        m_value = m_engine->makeJSValue(value);
+        JSValueProtect(context(), m_value);
+    }
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value)
+    : m_state(JSNative)
+{
+    if (!engine) {
+        // slower path reinitialization
+        m_state = CSpecial;
+        m_number = value;
+        m_value = 0;
+    } else {
+        m_engine = QScriptEnginePrivate::get(engine);
+        m_value = m_engine->makeJSValue(value);
+        JSValueProtect(context(), m_value);
+    }
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value)
+    : m_state(JSValue)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(value)
+{
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object)
+    : m_state(JSObject)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(value)
+    , m_object(object)
+{
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
+}
+
+bool QScriptValuePrivate::isValid() const { return m_state != Invalid; }
+
+bool QScriptValuePrivate::isBool()
+{
+    switch (m_state) {
+    case CBool:
+        return true;
+    case JSValue:
+        if (isObject())
+            return false;
+        // Fall-through.
+    case JSNative:
+        return JSValueIsBoolean(context(), value());
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isNumber()
+{
+    switch (m_state) {
+    case CNumber:
+        return m_number;
+    case JSValue:
+        if (isObject())
+            return false;
+        // Fall-through.
+    case JSNative:
+        return JSValueIsNumber(context(), value());
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isNull()
+{
+    switch (m_state) {
+    case CSpecial:
+        return m_number == static_cast<int>(QScriptValue::NullValue);
+    case JSValue:
+        if (isObject())
+            return false;
+        // Fall-through.
+    case JSNative:
+        return JSValueIsNull(context(), value());
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isString()
+{
+    switch (m_state) {
+    case CString:
+        return true;
+    case JSValue:
+        if (isObject())
+            return false;
+        // Fall-through.
+    case JSNative:
+        return JSValueIsString(context(), value());
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isUndefined()
+{
+    switch (m_state) {
+    case CSpecial:
+        return m_number == static_cast<int>(QScriptValue::UndefinedValue);
+    case JSValue:
+        if (isObject())
+            return false;
+        // Fall-through.
+    case JSNative:
+        return JSValueIsUndefined(context(), value());
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isError()
+{
+    switch (m_state) {
+    case JSValue:
+        if (!isObject())
+            return false;
+        // Fall-through.
+    case JSObject:
+        return inherits("Error");
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isObject()
+{
+    switch (m_state) {
+    case JSObject:
+        return true;
+    case JSValue:
+        m_object = JSValueToObject(context(), value(), /* exception */ 0);
+        if (!m_object)
+            return false;
+        m_state = JSObject;
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool QScriptValuePrivate::isFunction()
+{
+    switch (m_state) {
+    case JSValue:
+        m_object = JSValueToObject(context(), value(), /* exception */ 0);
+        if (!m_object)
+            return false;
+        m_state = JSObject;
+        // Fall-through.
+    case JSObject:
+        return JSObjectIsFunction(context(), object());
+    default:
+        return false;
+    }
+}
+
+QString QScriptValuePrivate::toString() const
+{
+    switch (m_state) {
+    case Invalid:
+        return QString();
+    case CBool:
+        return m_number ? QString::fromLatin1("true") : QString::fromLatin1("false");
+    case CString:
+        return m_string;
+    case CNumber:
+        return QString::number(m_number);
+    case CSpecial:
+        return m_number == QScriptValue::NullValue ? QString::fromLatin1("null") : QString::fromLatin1("undefined");
+    case JSValue:
+    case JSNative:
+    case JSObject:
+        return QScriptConverter::toString(JSValueToStringCopy(context(), value(), /* exception */ 0));
+    }
+
+    Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement.");
+    return QString(); // Avoid compiler warning.
+}
+
+qsreal QScriptValuePrivate::toNumber() const
+{
+    // TODO Check it.
+    switch (m_state) {
+    case JSValue:
+    case JSNative:
+    case JSObject:
+        return JSValueToNumber(context(), value(), /* exception */ 0);
+    case CNumber:
+    case CBool:
+        return m_number;
+    case Invalid:
+    case CSpecial:
+        return false;
+    case CString:
+        return m_string.isEmpty();
+    }
+
+    Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
+    return 0; // Avoid compiler warning.
+}
+
+bool QScriptValuePrivate::toBool() const
+{
+    switch (m_state) {
+    case JSValue:
+    case JSNative:
+    case JSObject:
+        return JSValueToBoolean(context(), value());
+    case CNumber:
+    case CBool:
+        return m_number;
+    case Invalid:
+    case CSpecial:
+        return false;
+    case CString:
+        return m_string.isEmpty();
+    }
+
+    Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
+    return false; // Avoid compiler warning.
+}
+
+qsreal QScriptValuePrivate::toInteger() const
+{
+    // TODO it is not true implementation!
+    return toNumber();
+}
+
+qint32 QScriptValuePrivate::toInt32() const
+{
+    // TODO it is not true implementation!
+    return toNumber();
+}
+
+quint32 QScriptValuePrivate::toUInt32() const
+{
+    // TODO it is not true implementation!
+    return toNumber();
+}
+
+quint16 QScriptValuePrivate::toUInt16() const
+{
+    // TODO it is not true implementation!
+    return toNumber();
+}
+
+
+bool QScriptValuePrivate::equals(QScriptValuePrivate* other)
+{
+    if (!isValid() || !other->isValid())
+        return false;
+
+    if ((m_state == other->m_state) && !isJSBased()) {
+        if (isNumberBased())
+            return m_number == other->m_number;
+        return m_string == other->m_string;
+    }
+
+    if (isJSBased() && !other->isJSBased()) {
+        if (!other->assignEngine(engine())) {
+            qWarning("equals(): Cannot compare to a value created in a different engine");
+            return false;
+        }
+    } else if (!isJSBased() && other->isJSBased()) {
+        if (!other->assignEngine(other->engine())) {
+            qWarning("equals(): Cannot compare to a value created in a different engine");
+            return false;
+        }
+    }
+
+    return JSValueIsEqual(context(), value(), other->value(), /* exception */ 0);
+}
+
+bool QScriptValuePrivate::strictlyEquals(const QScriptValuePrivate* other) const
+{
+    if (m_state != other->m_state)
+        return false;
+    if (isJSBased()) {
+        if (other->engine() != engine()) {
+            qWarning("strictlyEquals(): Cannot compare to a value created in a different engine");
+            return false;
+        }
+        return JSValueIsStrictEqual(context(), value(), other->value());
+    }
+    if (isStringBased())
+        return m_string == other->m_string;
+    if (isNumberBased())
+        return m_number == other->m_number;
+
+    return false; // Invalid state.
+}
+
+/*!
+  Tries to assign \a engine to this value. Returns true on success; otherwise returns false.
+*/
+bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
+{
+    JSValueRef value;
+    switch (m_state) {
+    case CBool:
+        value = engine->makeJSValue(static_cast<bool>(m_number));
+        break;
+    case CString:
+        value = engine->makeJSValue(m_string);
+        break;
+    case CNumber:
+        value = engine->makeJSValue(m_number);
+        break;
+    case CSpecial:
+        value = engine->makeJSValue(static_cast<QScriptValue::SpecialValue>(m_number));
+        break;
+    default:
+        if (!isJSBased())
+            Q_ASSERT_X(!isJSBased(), "assignEngine()", "Not all states are included in the previous switch statement.");
+        else
+            qWarning("JSValue can't be rassigned to an another engine.");
+        return false;
+    }
+    m_engine = engine;
+    m_state = JSNative;
+    setValue(value);
+    return true;
+}
+
+QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args)
+{
+    switch (m_state) {
+    case JSValue:
+        m_object = JSValueToObject(context(), value(), /* exception */ 0);
+        if (!object()) {
+            m_state = JSValue;
+            return new QScriptValuePrivate;
+        }
+        m_state = JSObject;
+        // Fall-through.
+    case JSObject:
+        {
+            // Convert all arguments and bind to the engine.
+            int argc = args.size();
+            JSValueRef argv[argc];
+            QScriptValueList::const_iterator i = args.constBegin();
+            for (int j = 0; i != args.constEnd(); j++, i++) {
+                QScriptValuePrivate* value = QScriptValuePrivate::get(*i);
+                if (!value->assignEngine(engine())) {
+                    qWarning("QScriptValue::call() failed: cannot call function with values created in a different engine");
+                    return new QScriptValuePrivate;
+                }
+                argv[j] = value->value();
+            }
+
+            // Make the call
+            JSValueRef exception = 0;
+            JSValueRef result = JSObjectCallAsFunction(context(), object(), /* thisObject */ 0, argc, argv, &exception);
+            if (!result && exception)
+                return new QScriptValuePrivate(engine(), exception);
+            if (result && !exception)
+                return new QScriptValuePrivate(engine(), result);
+        }
+        // this QSV is not a function <-- !result && !exception. Fall-through.
+    default:
+        return new QScriptValuePrivate;
+    }
+}
+
+QScriptEnginePrivate* QScriptValuePrivate::engine() const
+{
+    // As long as m_engine is an autoinitializated pointer we can safely return it without
+    // checking current state.
+    return m_engine.data();
+}
+
+JSGlobalContextRef QScriptValuePrivate::context() const
+{
+    Q_ASSERT(isJSBased());
+    return m_engine->context();
+}
+
+JSValueRef QScriptValuePrivate::value() const
+{
+    Q_ASSERT(isJSBased());
+    return m_value;
+}
+
+JSObjectRef QScriptValuePrivate::object() const
+{
+    Q_ASSERT(m_state == JSObject);
+    return m_object;
+}
+
+void QScriptValuePrivate::setValue(JSValueRef value)
+{
+    if (m_value)
+        JSValueUnprotect(context(), m_value);
+    if (value)
+        JSValueProtect(context(), value);
+    m_value = value;
+}
+
+/*!
+  \internal
+  Returns true if QSV is created from constructor with the given \a name, it has to be a
+  built-in type.
+*/
+bool QScriptValuePrivate::inherits(const char* name)
+{
+    Q_ASSERT(isJSBased());
+    JSObjectRef globalObject = JSContextGetGlobalObject(context());
+    JSValueRef error = JSObjectGetProperty(context(), globalObject, QScriptConverter::toString(name), 0);
+    return JSValueIsInstanceOfConstructor(context(), value(), JSValueToObject(context(), error, /* exception */ 0), /* exception */ 0);
+}
+
+/*!
+  \internal
+  Returns true if QSV have an engine associated.
+*/
+bool QScriptValuePrivate::isJSBased() const { return m_state >= JSValue; }
+
+/*!
+  \internal
+  Returns true if current value of QSV is placed in m_number.
+*/
+bool QScriptValuePrivate::isNumberBased() const { return !isJSBased() && !isStringBased() && m_state != Invalid; }
+
+/*!
+  \internal
+  Returns true if current value of QSV is placed in m_string.
+*/
+bool QScriptValuePrivate::isStringBased() const { return m_state == CString; }
+
+#endif // qscriptvalue_p_h
diff --git a/JavaScriptCore/qt/api/qtscriptglobal.h b/JavaScriptCore/qt/api/qtscriptglobal.h
new file mode 100644 (file)
index 0000000..29749c0
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+    Copyright (C) 2008 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.
+*/
+
+#ifndef qtscriptglobal_h
+#define qtscriptglobal_h
+
+#include <QtCore/qglobal.h>
+
+#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
+#  if defined(QT_NODLL)
+#  elif defined(QT_MAKEDLL)        /* create a Qt DLL library */
+#    if defined(QT_BUILD_JAVASCRIPT_LIB)
+#      define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
+#    else
+#      define Q_JAVASCRIPT_EXPORT Q_DECL_IMPORT
+#    endif
+#  elif defined(QT_DLL) /* use a Qt DLL library */
+#    define Q_JAVASCRIPT_EXPORT
+#  endif
+#endif
+
+#if defined(QT_SHARED)
+#  define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
+#else
+#  define Q_JAVASCRIPT_EXPORT
+#endif
+
+#endif
diff --git a/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro b/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro
new file mode 100644 (file)
index 0000000..0dc0902
--- /dev/null
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_qscriptengine
+QT += testlib
+include(../tests.pri)
+
+SOURCES += tst_qscriptengine.cpp
+
diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
new file mode 100644 (file)
index 0000000..37f3d11
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Copyright (C) 2009 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 <QtTest/qtest.h>
+
+class tst_QScriptEngine : public QObject {
+    Q_OBJECT
+
+public:
+    tst_QScriptEngine() {}
+    virtual ~tst_QScriptEngine() {}
+
+public slots:
+    void init() {}
+    void cleanup() {}
+
+private slots:
+    void evaluate();
+    void collectGarbage();
+};
+
+/* Evaluating a script that throw an unhandled exception should return an invalid value. */
+void tst_QScriptEngine::evaluate()
+{
+    QScriptEngine engine;
+    QVERIFY2(engine.evaluate("1+1").isValid(), "the expression should be evaluated and an valid result should be returned");
+    QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value");
+}
+
+/* Test garbage collection, at least try to not crash. */
+void tst_QScriptEngine::collectGarbage()
+{
+    QScriptEngine engine;
+    QScriptValue foo = engine.evaluate("( function foo() {return 'pong';} )");
+    QVERIFY(foo.isFunction());
+    engine.collectGarbage();
+    QCOMPARE(foo.call().toString(), QString::fromAscii("pong"));
+}
+QTEST_MAIN(tst_QScriptEngine)
+#include "tst_qscriptengine.moc"
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro b/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro
new file mode 100644 (file)
index 0000000..1ce5bc3
--- /dev/null
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_qscriptvalue
+QT += testlib
+include(../tests.pri)
+
+SOURCES += tst_qscriptvalue.cpp
+
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
new file mode 100644 (file)
index 0000000..336a1a6
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+    Copyright (C) 2009 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 <QtTest/qtest.h>
+
+Q_DECLARE_METATYPE(QScriptValue*);
+Q_DECLARE_METATYPE(QScriptValue);
+
+class tst_QScriptValue : public QObject {
+    Q_OBJECT
+
+public:
+    tst_QScriptValue() {}
+    virtual ~tst_QScriptValue() {}
+
+private slots:
+    void toString_data();
+    void toString();
+    void copyConstructor_data();
+    void copyConstructor();
+    void assignOperator_data();
+    void assignOperator();
+    void dataSharing();
+    void constructors_data();
+    void constructors();
+    void call();
+
+    // copied from Qt's QtScript.
+    void ctor();
+};
+
+void tst_QScriptValue::ctor()
+{
+    QScriptEngine eng;
+    {
+        QScriptValue v;
+        QCOMPARE(v.isValid(), false);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(&eng, QScriptValue::UndefinedValue);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isUndefined(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(&eng, QScriptValue::NullValue);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNull(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(&eng, false);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isBoolean(), true);
+        QCOMPARE(v.isBool(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toBoolean(), false);
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(&eng, int(1));
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNumber(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toNumber(), 1.0);
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(int(0x43211234));
+        QVERIFY(v.isNumber());
+        QCOMPARE(v.toInt32(), 0x43211234);
+    }
+    {
+        QScriptValue v(&eng, uint(1));
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNumber(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toNumber(), 1.0);
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(uint(0x43211234));
+        QVERIFY(v.isNumber());
+        QCOMPARE(v.toUInt32(), uint(0x43211234));
+    }
+    {
+        QScriptValue v(&eng, 1.0);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNumber(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toNumber(), 1.0);
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(12345678910.5);
+        QVERIFY(v.isNumber());
+        QCOMPARE(v.toNumber(), 12345678910.5);
+    }
+    {
+        QScriptValue v(&eng, "ciao");
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isString(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toString(), QLatin1String("ciao"));
+        QCOMPARE(v.engine(), &eng);
+    }
+    {
+        QScriptValue v(&eng, QString("ciao"));
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isString(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toString(), QLatin1String("ciao"));
+        QCOMPARE(v.engine(), &eng);
+    }
+    // copy constructor, operator=
+    {
+        QScriptValue v(&eng, 1.0);
+        QScriptValue v2(v);
+        QCOMPARE(v2.strictlyEquals(v), true);
+        QCOMPARE(v2.engine(), &eng);
+
+        QScriptValue v3(v);
+        QCOMPARE(v3.strictlyEquals(v), true);
+        QCOMPARE(v3.strictlyEquals(v2), true);
+        QCOMPARE(v3.engine(), &eng);
+
+        QScriptValue v4(&eng, 2.0);
+        QCOMPARE(v4.strictlyEquals(v), false);
+        v3 = v4;
+        QCOMPARE(v3.strictlyEquals(v), false);
+        QCOMPARE(v3.strictlyEquals(v4), true);
+
+        v2 = QScriptValue();
+        QCOMPARE(v2.strictlyEquals(v), false);
+        QCOMPARE(v.toNumber(), 1.0);
+
+        QScriptValue v5(v);
+        QCOMPARE(v5.strictlyEquals(v), true);
+        v = QScriptValue();
+        QCOMPARE(v5.strictlyEquals(v), false);
+        QCOMPARE(v5.toNumber(), 1.0);
+    }
+
+    // constructors that take no engine argument
+    {
+        QScriptValue v(QScriptValue::UndefinedValue);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isUndefined(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(QScriptValue::NullValue);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNull(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(false);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isBoolean(), true);
+        QCOMPARE(v.isBool(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toBoolean(), false);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(int(1));
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNumber(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toNumber(), 1.0);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(uint(1));
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNumber(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toNumber(), 1.0);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(1.0);
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isNumber(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toNumber(), 1.0);
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v("ciao");
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isString(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toString(), QLatin1String("ciao"));
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    {
+        QScriptValue v(QString("ciao"));
+        QCOMPARE(v.isValid(), true);
+        QCOMPARE(v.isString(), true);
+        QCOMPARE(v.isObject(), false);
+        QCOMPARE(v.toString(), QLatin1String("ciao"));
+        QCOMPARE(v.engine(), (QScriptEngine *)0);
+    }
+    // copy constructor, operator=
+    {
+        QScriptValue v(1.0);
+        QScriptValue v2(v);
+        QCOMPARE(v2.strictlyEquals(v), true);
+        QCOMPARE(v2.engine(), (QScriptEngine *)0);
+
+        QScriptValue v3(v);
+        QCOMPARE(v3.strictlyEquals(v), true);
+        QCOMPARE(v3.strictlyEquals(v2), true);
+        QCOMPARE(v3.engine(), (QScriptEngine *)0);
+
+        QScriptValue v4(2.0);
+        QCOMPARE(v4.strictlyEquals(v), false);
+        v3 = v4;
+        QCOMPARE(v3.strictlyEquals(v), false);
+        QCOMPARE(v3.strictlyEquals(v4), true);
+
+        v2 = QScriptValue();
+        QCOMPARE(v2.strictlyEquals(v), false);
+        QCOMPARE(v.toNumber(), 1.0);
+
+        QScriptValue v5(v);
+        QCOMPARE(v5.strictlyEquals(v), true);
+        v = QScriptValue();
+        QCOMPARE(v5.strictlyEquals(v), false);
+        QCOMPARE(v5.toNumber(), 1.0);
+    }
+
+    // 0 engine
+    QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined());
+    QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull());
+    QVERIFY(QScriptValue(0, false).isBool());
+    QVERIFY(QScriptValue(0, int(1)).isNumber());
+    QVERIFY(QScriptValue(0, uint(1)).isNumber());
+    QVERIFY(QScriptValue(0, 1.0).isNumber());
+    QVERIFY(QScriptValue(0, "ciao").isString());
+    QVERIFY(QScriptValue(0, QString("ciao")).isString());
+}
+
+void tst_QScriptValue::toString_data()
+{
+    QTest::addColumn<QString>("code");
+    QTest::addColumn<QString>("result");
+
+    QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello");
+    QTest::newRow("string utf") << QString::fromUtf8("'ąśćżźółńę'") << QString::fromUtf8("ąśćżźółńę");
+    QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5");
+    QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null");
+    QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false");
+    QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined");
+    QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]");
+}
+
+/* Test conversion to string from different JSC types */
+void tst_QScriptValue::toString()
+{
+    QFETCH(QString, code);
+    QFETCH(QString, result);
+
+    QScriptEngine engine;
+    QCOMPARE(engine.evaluate(code).toString(), result);
+}
+
+void tst_QScriptValue::copyConstructor_data()
+{
+    QScriptEngine engine;
+    QScriptValue nnumber(123);
+    QScriptValue nstring("ping");
+    QScriptValue number(engine.evaluate("1"));
+    QScriptValue string(engine.evaluate("'foo'"));
+    QScriptValue object(engine.evaluate("new Object"));
+    QScriptValue undefined(engine.evaluate("undefined"));
+    QScriptValue null(engine.evaluate("null"));
+
+    QTest::addColumn<QScriptValue>("value");
+    QTest::addColumn<QString>("result");
+
+    QTest::newRow("native number") << nnumber << QString::number(123);
+    QTest::newRow("native string") << nstring << QString("ping");
+    QTest::newRow("number") << number << QString::fromAscii("1");
+    QTest::newRow("string") << string << QString::fromAscii("foo");
+    QTest::newRow("object") << object << QString::fromAscii("[object Object]");
+    QTest::newRow("undefined") << undefined << QString::fromAscii("undefined");
+    QTest::newRow("null") << null << QString::fromAscii("null");
+}
+
+void tst_QScriptValue::copyConstructor()
+{
+    QFETCH(QScriptValue, value);
+    QFETCH(QString, result);
+
+    QVERIFY(value.isValid());
+    QScriptValue tmp(value);
+    QVERIFY(tmp.isValid());
+    QCOMPARE(tmp.toString(), result);
+}
+
+void tst_QScriptValue::assignOperator_data()
+{
+    copyConstructor_data();
+}
+
+void tst_QScriptValue::assignOperator()
+{
+    QFETCH(QScriptValue, value);
+    QFETCH(QString, result);
+
+    QScriptValue tmp;
+    tmp = value;
+    QVERIFY(tmp.isValid());
+    QCOMPARE(tmp.toString(), result);
+}
+
+/* Test internal data sharing between a diffrenet QScriptValue. */
+void tst_QScriptValue::dataSharing()
+{
+    QScriptEngine engine;
+    QScriptValue v1;
+    QScriptValue v2(v1);
+
+    v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid.
+    QVERIFY(v1.isValid());
+    QVERIFY(!v2.isValid());
+
+    v2 = v1; // v1 == 1; v2 == 1.
+    QVERIFY(v1.isValid());
+    QVERIFY(v2.isValid());
+
+    v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1.
+    QVERIFY(v1.isValid());
+    QVERIFY(v2.isValid());
+    QVERIFY(v2.toString() != v1.toString());
+
+    // TODO add object manipulation (v1 and v2 point to the same object).
+}
+
+void tst_QScriptValue::constructors_data()
+{
+    QScriptEngine engine;
+
+    QTest::addColumn<QScriptValue>("value");
+    QTest::addColumn<QString>("string");
+    QTest::addColumn<bool>("valid");
+    QTest::addColumn<bool>("object");
+
+    QTest::newRow("invalid") << QScriptValue() << QString() << false << false;
+    QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false;
+    QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false;
+    QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false;
+    QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false;
+    QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true;
+    QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false;
+    QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false;
+}
+
+void tst_QScriptValue::constructors()
+{
+    QFETCH(QScriptValue, value);
+    QFETCH(QString, string);
+    QFETCH(bool, valid);
+    QFETCH(bool, object);
+
+    QCOMPARE(value.isValid(), valid);
+    QCOMPARE(value.toString(), string);
+    QCOMPARE(value.isObject(), object);
+}
+
+void tst_QScriptValue::call()
+{
+    QScriptEngine engine;
+    QScriptValue ping = engine.evaluate("( function() {return 'ping';} )");
+    QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )");
+    QScriptValue one(1);
+    QScriptValue five(5);
+    QScriptValue result;
+
+    QVERIFY(one.isValid());
+    QVERIFY(five.isValid());
+
+    QVERIFY(ping.isValid());
+    QVERIFY(ping.isFunction());
+    result = ping.call();
+    QVERIFY(result.isValid());
+    QCOMPARE(result.toString(), QString::fromUtf8("ping"));
+
+    QVERIFY(incr.isValid());
+    QVERIFY(incr.isFunction());
+    result = incr.call(QScriptValue(), QScriptValueList() << one);
+    QVERIFY(result.isValid());
+    QCOMPARE(result.toString(), QString("2"));
+
+    QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6"));
+
+    QVERIFY(incr.call().isValid()); // Exception.
+}
+
+QTEST_MAIN(tst_QScriptValue)
+#include "tst_qscriptvalue.moc"
diff --git a/JavaScriptCore/qt/tests/tests.pri b/JavaScriptCore/qt/tests/tests.pri
new file mode 100644 (file)
index 0000000..1ce238f
--- /dev/null
@@ -0,0 +1,28 @@
+isEmpty(OUTPUT_DIR) {
+    CONFIG(debug, debug|release) {
+        OUTPUT_DIR=$$PWD/WebKitBuild/Debug
+    } else { # Release
+        OUTPUT_DIR=$$PWD/WebKitBuild/Release
+    }
+}
+
+
+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/tests/tests.pro b/JavaScriptCore/qt/tests/tests.pro
new file mode 100644 (file)
index 0000000..6e5edb1
--- /dev/null
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS =   qscriptengine \
+            qscriptvalue
index 9b5d250..29a3a8e 100644 (file)
@@ -21,4 +21,10 @@ SUBDIRS += \
 
 }
 
+build-qtscript {
+    SUBDIRS += \
+        JavaScriptCore/qt/api/QtScript.pro \
+        JavaScriptCore/qt/tests
+}
+
 include(WebKit/qt/docs/docs.pri)
index 340c375..bc4019d 100644 (file)
@@ -1,3 +1,21 @@
+2010-01-26  Jedrzej Nowacki  <jedrzej.nowacki@nokia.com>
+
+        Reviewed by Simon Hausmann.
+
+        First steps of the QtScript API.
+        
+        Two new classes were created; QScriptEngine and QScriptValue.
+        The first should encapsulate a javascript context and the second a script
+        value.
+        
+        This API is still in development, so it isn't compiled by default.
+        To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to
+        build-webkit.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32565
+
+        * docs/qtwebkit.qdocconf:
+
 2010-01-26  Holger Hans Peter Freyther  <zecke@selfish.org>
 
         Reviewed by Simon Hausmann.
index 8ee8f69..292c124 100644 (file)
@@ -4,7 +4,7 @@ project     = qtwebkit
 description = "Qt WebKit API Documentation"
 
 headerdirs = $SRCDIR/WebKit/qt/Api
-sourcedirs = $SRCDIR/WebKit/qt/Api $SRCDIR/WebKit/qt/docs
+sourcedirs = $SRCDIR/WebKit/qt/Api $SRCDIR/WebKit/qt/docs $SRCDIR/JavaScriptCore/qt/api
 outputdir = $OUTPUT_DIR/doc/html
 outputformats = HTML
 sources.fileextensions  = "*.cpp *.doc *.qdoc *.h"