diff options
author | Steve Block <steveblock@google.com> | 2010-02-02 14:57:50 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-04 15:06:55 +0000 |
commit | d0825bca7fe65beaee391d30da42e937db621564 (patch) | |
tree | 7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /JavaScriptCore/qt/api | |
parent | 3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff) | |
download | external_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2 |
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'JavaScriptCore/qt/api')
-rw-r--r-- | JavaScriptCore/qt/api/QtScript.pro | 36 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptconverter_p.h | 50 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptengine.cpp | 88 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptengine.h | 47 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptengine_p.cpp | 54 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptengine_p.h | 98 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalue.cpp | 556 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalue.h | 99 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qscriptvalue_p.h | 719 | ||||
-rw-r--r-- | JavaScriptCore/qt/api/qtscriptglobal.h | 44 |
10 files changed, 1791 insertions, 0 deletions
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro new file mode 100644 index 0000000..c87eaf4 --- /dev/null +++ b/JavaScriptCore/qt/api/QtScript.pro @@ -0,0 +1,36 @@ +TARGET = QtScript +TEMPLATE = lib +QT = core + +INCLUDEPATH += $$PWD + +CONFIG += building-libs + +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 index 0000000..c3ca41f --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptconverter_p.h @@ -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 index 0000000..f12f410 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine.cpp @@ -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 index 0000000..cf61d35 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine.h @@ -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 index 0000000..de8a355 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp @@ -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 index 0000000..8e27c42 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine_p.h @@ -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 index 0000000..127fe04 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalue.cpp @@ -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 index 0000000..d45aed3 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalue.h @@ -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 index 0000000..6a5b388 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalue_p.h @@ -0,0 +1,719 @@ +/* + 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> +#include <QtCore/qvarlengtharray.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(); + QVarLengthArray<JSValueRef, 8> 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.constData(), &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 index 0000000..29749c0 --- /dev/null +++ b/JavaScriptCore/qt/api/qtscriptglobal.h @@ -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 |