summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/qt/api
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/qt/api')
-rw-r--r--Source/JavaScriptCore/qt/api/QtScript.pro51
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptconverter_p.h146
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptengine.cpp426
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptengine.h82
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptengine_p.cpp167
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptengine_p.h259
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptfunction.cpp145
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptfunction_p.h57
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h209
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptprogram.cpp136
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptprogram.h53
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptprogram_p.h133
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptstring.cpp131
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptstring.h58
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptstring_p.h124
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp148
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h50
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h73
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptvalue.cpp802
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptvalue.h140
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptvalue_p.h1220
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp226
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptvalueiterator.h63
-rw-r--r--Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h172
-rw-r--r--Source/JavaScriptCore/qt/api/qtscriptglobal.h43
25 files changed, 5114 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/qt/api/QtScript.pro b/Source/JavaScriptCore/qt/api/QtScript.pro
new file mode 100644
index 0000000..490758c
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/QtScript.pro
@@ -0,0 +1,51 @@
+TARGET = QtScript
+TEMPLATE = lib
+QT = core
+
+INCLUDEPATH += $$PWD
+
+CONFIG += building-libs
+
+isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = ../../generated
+!CONFIG(release, debug|release) {
+ OBJECTS_DIR = obj/debug
+} else { # Release
+ OBJECTS_DIR = obj/release
+}
+
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../..
+include($$PWD/../../../WebKit.pri)
+
+include($$PWD/../../JavaScriptCore.pri)
+addJavaScriptCoreLib(../..)
+
+INCLUDEPATH += $$PWD/../../API
+
+SOURCES += $$PWD/qscriptengine.cpp \
+ $$PWD/qscriptengine_p.cpp \
+ $$PWD/qscriptvalue.cpp \
+ $$PWD/qscriptvalueiterator.cpp \
+ $$PWD/qscriptstring.cpp \
+ $$PWD/qscriptprogram.cpp \
+ $$PWD/qscriptsyntaxcheckresult.cpp \
+ $$PWD/qscriptfunction.cpp
+
+HEADERS += $$PWD/qtscriptglobal.h \
+ $$PWD/qscriptengine.h \
+ $$PWD/qscriptengine_p.h \
+ $$PWD/qscriptvalue.h \
+ $$PWD/qscriptvalue_p.h \
+ $$PWD/qscriptvalueiterator.h \
+ $$PWD/qscriptvalueiterator_p.h \
+ $$PWD/qscriptconverter_p.h \
+ $$PWD/qscriptstring.h \
+ $$PWD/qscriptstring_p.h \
+ $$PWD/qscriptprogram.h \
+ $$PWD/qscriptprogram_p.h \
+ $$PWD/qscriptsyntaxcheckresult.h \
+ $$PWD/qscriptoriginalglobalobject_p.h \
+ $$PWD/qscriptfunction_p.h
+
+!static: DEFINES += QT_MAKEDLL
+
+DESTDIR = $$OUTPUT_DIR/lib
diff --git a/Source/JavaScriptCore/qt/api/qscriptconverter_p.h b/Source/JavaScriptCore/qt/api/qscriptconverter_p.h
new file mode 100644
index 0000000..0c57d95
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptconverter_p.h
@@ -0,0 +1,146 @@
+/*
+ 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 "qscriptvalue.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
+
+extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str);
+
+/*
+ \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 quint32 toArrayIndex(const JSStringRef jsstring)
+ {
+ // FIXME this function should be exported by JSC C API.
+ QString qstring = toString(jsstring);
+
+ bool ok;
+ quint32 idx = qstring.toUInt(&ok);
+ if (!ok || toString(idx) != qstring)
+ idx = 0xffffffff;
+
+ return idx;
+ }
+
+ 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);
+ }
+ static QString toString(double value)
+ {
+ // FIXME this should be easier. The ideal fix is to create
+ // a new function in JSC C API which could cover the functionality.
+
+ if (qIsNaN(value))
+ return QString::fromLatin1("NaN");
+ if (qIsInf(value))
+ return QString::fromLatin1(value < 0 ? "-Infinity" : "Infinity");
+ if (!value)
+ return QString::fromLatin1("0");
+
+ QVarLengthArray<char, 25> buf;
+ int decpt;
+ int sign;
+ char* result = 0;
+ char* endresult;
+ (void)qdtoa(value, 0, 0, &decpt, &sign, &endresult, &result);
+
+ if (!result)
+ return QString();
+
+ int resultLen = endresult - result;
+ if (decpt <= 0 && decpt > -6) {
+ buf.resize(-decpt + 2 + sign);
+ qMemSet(buf.data(), '0', -decpt + 2 + sign);
+ if (sign) // fix the sign.
+ buf[0] = '-';
+ buf[sign + 1] = '.';
+ buf.append(result, resultLen);
+ } else {
+ if (sign)
+ buf.append('-');
+ int length = buf.size() - sign + resultLen;
+ if (decpt <= 21 && decpt > 0) {
+ if (length <= decpt) {
+ const char* zeros = "0000000000000000000000000";
+ buf.append(result, resultLen);
+ buf.append(zeros, decpt - length);
+ } else {
+ buf.append(result, decpt);
+ buf.append('.');
+ buf.append(result + decpt, resultLen - decpt);
+ }
+ } else if (result[0] >= '0' && result[0] <= '9') {
+ if (length > 1) {
+ buf.append(result, 1);
+ buf.append('.');
+ buf.append(result + 1, resultLen - 1);
+ } else
+ buf.append(result, resultLen);
+ buf.append('e');
+ buf.append(decpt >= 0 ? '+' : '-');
+ int e = qAbs(decpt - 1);
+ if (e >= 100)
+ buf.append('0' + e / 100);
+ if (e >= 10)
+ buf.append('0' + (e % 100) / 10);
+ buf.append('0' + e % 10);
+ }
+ }
+ free(result);
+ buf.append(0);
+ return QString::fromLatin1(buf.constData());
+ }
+
+ static JSPropertyAttributes toPropertyFlags(const QFlags<QScriptValue::PropertyFlag>& flags)
+ {
+ JSPropertyAttributes attr = 0;
+ if (flags.testFlag(QScriptValue::ReadOnly))
+ attr |= kJSPropertyAttributeReadOnly;
+ if (flags.testFlag(QScriptValue::Undeletable))
+ attr |= kJSPropertyAttributeDontDelete;
+ if (flags.testFlag(QScriptValue::SkipInEnumeration))
+ attr |= kJSPropertyAttributeDontEnum;
+ return attr;
+ }
+};
+
+#endif // qscriptconverter_p_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptengine.cpp b/Source/JavaScriptCore/qt/api/qscriptengine.cpp
new file mode 100644
index 0000000..607b0b9
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptengine.cpp
@@ -0,0 +1,426 @@
+/*
+ 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 "qscriptprogram_p.h"
+#include "qscriptsyntaxcheckresult_p.h"
+#include "qscriptvalue_p.h"
+#include <QtCore/qdatetime.h>
+#include <QtCore/qnumeric.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()
+{
+}
+
+/*!
+ Checks the syntax of the given \a program. Returns a
+ QScriptSyntaxCheckResult object that contains the result of the check.
+*/
+QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program)
+{
+ // FIXME This is not optimal.
+ // The JSC C API needs a context to perform a syntax check, it means that a QScriptEnginePrivate
+ // had to be created. This function is static so we have to create QScriptEnginePrivate for each
+ // call. We can't remove the "static" for compatibility reason, at least up to Qt5.
+ // QScriptSyntaxCheckResultPrivate takes ownership of newly created engine. The engine will be
+ // kept as long as it is needed for lazy evaluation of properties of
+ // the QScriptSyntaxCheckResultPrivate.
+ QScriptEnginePrivate* engine = new QScriptEnginePrivate(/* q_ptr */ 0);
+ return QScriptSyntaxCheckResultPrivate::get(engine->checkSyntax(program));
+}
+
+/*!
+ 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));
+}
+
+QScriptValue QScriptEngine::evaluate(const QScriptProgram& program)
+{
+ return QScriptValuePrivate::get(d_ptr->evaluate(QScriptProgramPrivate::get(program)));
+}
+
+/*!
+ Returns true if the last script evaluation resulted in an uncaught
+ exception; otherwise returns false.
+
+ The exception state is cleared when evaluate() is called.
+
+ \sa uncaughtException(), uncaughtExceptionLineNumber(),
+ uncaughtExceptionBacktrace()
+*/
+bool QScriptEngine::hasUncaughtException() const
+{
+ return d_ptr->hasUncaughtException();
+}
+
+/*!
+ Returns the current uncaught exception, or an invalid QScriptValue
+ if there is no uncaught exception.
+
+ The exception value is typically an \c{Error} object; in that case,
+ you can call toString() on the return value to obtain an error
+ message.
+
+ \sa hasUncaughtException(), uncaughtExceptionLineNumber(),
+ uncaughtExceptionBacktrace()
+*/
+QScriptValue QScriptEngine::uncaughtException() const
+{
+ return QScriptValuePrivate::get(d_ptr->uncaughtException());
+}
+
+/*!
+ Clears any uncaught exceptions in this engine.
+
+ \sa hasUncaughtException()
+*/
+void QScriptEngine::clearExceptions()
+{
+ d_ptr->clearExceptions();
+}
+
+/*!
+ Returns the line number where the last uncaught exception occurred.
+
+ Line numbers are 1-based, unless a different base was specified as
+ the second argument to evaluate().
+
+ \sa hasUncaughtException(), uncaughtExceptionBacktrace()
+*/
+int QScriptEngine::uncaughtExceptionLineNumber() const
+{
+ return d_ptr->uncaughtExceptionLineNumber();
+}
+
+/*!
+ Returns a human-readable backtrace of the last uncaught exception.
+
+ Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}.
+
+ \sa uncaughtException()
+*/
+QStringList QScriptEngine::uncaughtExceptionBacktrace() const
+{
+ return d_ptr->uncaughtExceptionBacktrace();
+}
+
+/*!
+ Runs the garbage collector.
+
+ The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
+ 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.
+
+ \sa reportAdditionalMemoryCost()
+*/
+void QScriptEngine::collectGarbage()
+{
+ d_ptr->collectGarbage();
+}
+
+/*!
+ Reports an additional memory cost of the given \a size, measured in
+ bytes, to the garbage collector.
+
+ This function can be called to indicate that a JavaScript object has
+ memory associated with it that isn't managed by Qt Script itself.
+ Reporting the additional cost makes it more likely that the garbage
+ collector will be triggered.
+
+ Note that if the additional memory is shared with objects outside
+ the scripting environment, the cost should not be reported, since
+ collecting the JavaScript object would not cause the memory to be
+ freed anyway.
+
+ Negative \a size values are ignored, i.e. this function can't be
+ used to report that the additional memory has been deallocated.
+
+ \sa collectGarbage()
+*/
+void QScriptEngine::reportAdditionalMemoryCost(int cost)
+{
+ d_ptr->reportAdditionalMemoryCost(cost);
+}
+
+/*!
+ Returns a handle that represents the given string, \a str.
+
+ QScriptString can be used to quickly look up properties, and
+ compare property names, of script objects.
+
+ \sa QScriptValue::property()
+*/
+QScriptString QScriptEngine::toStringHandle(const QString& str)
+{
+ return QScriptStringPrivate::get(d_ptr->toStringHandle(str));
+}
+
+/*!
+ Converts the given \a value to an object, if such a conversion is
+ possible; otherwise returns an invalid QScriptValue. The conversion
+ is performed according to the following table:
+
+ \table
+ \header \o Input Type \o Result
+ \row \o Undefined \o An invalid QScriptValue.
+ \row \o Null \o An invalid QScriptValue.
+ \row \o Boolean \o A new Boolean object whose internal value is set to the value of the boolean.
+ \row \o Number \o A new Number object whose internal value is set to the value of the number.
+ \row \o String \o A new String object whose internal value is set to the value of the string.
+ \row \o Object \o The result is the object itself (no conversion).
+ \endtable
+
+ \sa newObject()
+*/
+QScriptValue QScriptEngine::toObject(const QScriptValue& value)
+{
+ return QScriptValuePrivate::get(QScriptValuePrivate::get(value)->toObject(d_ptr.data()));
+}
+
+/*!
+ Returns a QScriptValue of the primitive type Null.
+
+ \sa undefinedValue()
+*/
+QScriptValue QScriptEngine::nullValue()
+{
+ return QScriptValue(this, QScriptValue::NullValue);
+}
+
+/*!
+ Returns a QScriptValue of the primitive type Undefined.
+
+ \sa nullValue()
+*/
+QScriptValue QScriptEngine::undefinedValue()
+{
+ return QScriptValue(this, QScriptValue::UndefinedValue);
+}
+
+/*!
+ Creates a QScriptValue that wraps a native (C++) function. \a fun
+ must be a C++ function with signature QScriptEngine::FunctionSignature.
+ \a length is the number of arguments that \a fun expects; this becomes
+ the \c{length} property of the created QScriptValue.
+
+ Note that \a length only gives an indication of the number of
+ arguments that the function expects; an actual invocation of a
+ function can include any number of arguments. You can check the
+ \l{QScriptContext::argumentCount()}{argumentCount()} of the
+ QScriptContext associated with the invocation to determine the
+ actual number of arguments passed.
+
+ A \c{prototype} property is automatically created for the resulting
+ function object, to provide for the possibility that the function
+ will be used as a constructor.
+
+ By combining newFunction() and the property flags
+ QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
+ can create script object properties that behave like normal
+ properties in script code, but are in fact accessed through
+ functions (analogous to how properties work in \l{Qt's Property
+ System}). Example:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
+
+ When the property \c{foo} of the script object is subsequently
+ accessed in script code, \c{getSetFoo()} will be invoked to handle
+ the access. In this particular case, we chose to store the "real"
+ value of \c{foo} as a property of the accessor function itself; you
+ are of course free to do whatever you like in this function.
+
+ In the above example, a single native function was used to handle
+ both reads and writes to the property; the argument count is used to
+ determine if we are handling a read or write. You can also use two
+ separate functions; just specify the relevant flag
+ (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
+ setting the property, e.g.:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
+
+ \sa QScriptValue::call()
+*/
+QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
+{
+ return QScriptValuePrivate::get(d_ptr->newFunction(fun, 0, length));
+}
+
+/*!
+ Creates a constructor function from \a fun, with the given \a length.
+ The \c{prototype} property of the resulting function is set to be the
+ given \a prototype. The \c{constructor} property of \a prototype is
+ set to be the resulting function.
+
+ When a function is called as a constructor (e.g. \c{new Foo()}), the
+ `this' object associated with the function call is the new object
+ that the function is expected to initialize; the prototype of this
+ default constructed object will be the function's public
+ \c{prototype} property. If you always want the function to behave as
+ a constructor (e.g. \c{Foo()} should also create a new object), or
+ if you need to create your own object rather than using the default
+ `this' object, you should make sure that the prototype of your
+ object is set correctly; either by setting it manually, or, when
+ wrapping a custom type, by having registered the defaultPrototype()
+ of that type. Example:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
+
+ To wrap a custom type and provide a constructor for it, you'd typically
+ do something like this:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
+*/
+QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, const QScriptValue& prototype, int length)
+{
+ return QScriptValuePrivate::get(d_ptr->newFunction(fun, QScriptValuePrivate::get(prototype), length));
+}
+
+/*!
+ \internal
+ \since 4.4
+*/
+QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
+{
+ return QScriptValuePrivate::get(d_ptr->newFunction(fun, arg));
+}
+
+/*!
+ Creates a QtScript object of class Object.
+
+ The prototype of the created object will be the Object
+ prototype object.
+
+ \sa newArray(), QScriptValue::setProperty()
+*/
+QScriptValue QScriptEngine::newObject()
+{
+ return QScriptValuePrivate::get(d_ptr->newObject());
+}
+
+/*!
+ Creates a QtScript object of class Array with the given \a length.
+
+ \sa newObject()
+*/
+QScriptValue QScriptEngine::newArray(uint length)
+{
+ return QScriptValuePrivate::get(d_ptr->newArray(length));
+}
+
+/*!
+ Creates a QtScript object of class Date with the given \a value
+ (the number of milliseconds since 01 January 1970, UTC).
+*/
+QScriptValue QScriptEngine::newDate(qsreal value)
+{
+ return QScriptValuePrivate::get(d_ptr->newDate(value));
+}
+
+/*!
+ Creates a QtScript object of class Date from the given \a value.
+
+ \sa QScriptValue::toDateTime()
+*/
+QScriptValue QScriptEngine::newDate(const QDateTime& value)
+{
+ if (value.isValid())
+ return QScriptValuePrivate::get(d_ptr->newDate(qsreal(value.toMSecsSinceEpoch())));
+ return QScriptValuePrivate::get(d_ptr->newDate(qSNaN()));
+}
+
+/*!
+ Returns this engine's Global Object.
+
+ By default, the Global Object contains the built-in objects that are
+ part of \l{ECMA-262}, such as Math, Date and String. Additionally,
+ you can set properties of the Global Object to make your own
+ extensions available to all script code. Non-local variables in
+ script code will be created as properties of the Global Object, as
+ well as local variables in global code.
+*/
+QScriptValue QScriptEngine::globalObject() const
+{
+ return QScriptValuePrivate::get(d_ptr->globalObject());
+}
+
+/*!
+ \typedef QScriptEngine::FunctionSignature
+ \relates QScriptEngine
+
+ The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}.
+
+ A function with such a signature can be passed to
+ QScriptEngine::newFunction() to wrap the function.
+*/
+
+/*!
+ \typedef QScriptEngine::FunctionWithArgSignature
+ \relates QScriptEngine
+
+ The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}.
+
+ A function with such a signature can be passed to
+ QScriptEngine::newFunction() to wrap the function.
+*/
diff --git a/Source/JavaScriptCore/qt/api/qscriptengine.h b/Source/JavaScriptCore/qt/api/qscriptengine.h
new file mode 100644
index 0000000..281707f
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptengine.h
@@ -0,0 +1,82 @@
+/*
+ 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 "qscriptprogram.h"
+#include "qscriptstring.h"
+#include "qscriptsyntaxcheckresult.h"
+#include "qscriptvalue.h"
+#include <QtCore/qobject.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QDateTime;
+class QScriptEnginePrivate;
+
+// FIXME: Remove this once QScriptContext is properly defined.
+typedef void QScriptContext;
+
+// Internal typedef
+typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr;
+
+class QScriptEngine : public QObject {
+public:
+ QScriptEngine();
+ ~QScriptEngine();
+
+ static QScriptSyntaxCheckResult checkSyntax(const QString& program);
+ QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
+ QScriptValue evaluate(const QScriptProgram& program);
+
+ bool hasUncaughtException() const;
+ QScriptValue uncaughtException() const;
+ void clearExceptions();
+ int uncaughtExceptionLineNumber() const;
+ QStringList uncaughtExceptionBacktrace() const;
+
+ void collectGarbage();
+ void reportAdditionalMemoryCost(int cost);
+
+ QScriptString toStringHandle(const QString& str);
+ QScriptValue toObject(const QScriptValue& value);
+
+ QScriptValue nullValue();
+ QScriptValue undefinedValue();
+
+ typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *);
+ typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *);
+
+ QScriptValue newFunction(FunctionSignature fun, int length = 0);
+ QScriptValue newFunction(FunctionSignature fun, const QScriptValue& prototype, int length = 0);
+ QScriptValue newFunction(FunctionWithArgSignature fun, void* arg);
+
+ QScriptValue newObject();
+ QScriptValue newArray(uint length = 0);
+ QScriptValue newDate(qsreal value);
+ QScriptValue newDate(const QDateTime& value);
+ QScriptValue globalObject() const;
+private:
+ friend class QScriptEnginePrivate;
+
+ QScriptEnginePtr d_ptr;
+};
+
+#endif
diff --git a/Source/JavaScriptCore/qt/api/qscriptengine_p.cpp b/Source/JavaScriptCore/qt/api/qscriptengine_p.cpp
new file mode 100644
index 0000000..89054c0
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -0,0 +1,167 @@
+/*
+ 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 "qscriptfunction_p.h"
+#include "qscriptprogram_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))
+ , m_exception(0)
+ , m_originalGlobalObject(m_context)
+ , m_nativeFunctionClass(JSClassCreate(&qt_NativeFunctionClass))
+ , m_nativeFunctionWithArgClass(JSClassCreate(&qt_NativeFunctionWithArgClass))
+{
+}
+
+QScriptEnginePrivate::~QScriptEnginePrivate()
+{
+ JSClassRelease(m_nativeFunctionClass);
+ JSClassRelease(m_nativeFunctionWithArgClass);
+ if (m_exception)
+ JSValueUnprotect(m_context, m_exception);
+ JSGlobalContextRelease(m_context);
+}
+
+QScriptSyntaxCheckResultPrivate* QScriptEnginePrivate::checkSyntax(const QString& program)
+{
+ JSValueRef exception;
+ JSStringRef source = QScriptConverter::toString(program);
+ bool syntaxIsCorrect = JSCheckScriptSyntax(m_context, source, /* url */ 0, /* starting line */ 1, &exception);
+ JSStringRelease(source);
+ if (syntaxIsCorrect) {
+ return new QScriptSyntaxCheckResultPrivate(this);
+ }
+ JSValueProtect(m_context, exception);
+ return new QScriptSyntaxCheckResultPrivate(this, const_cast<JSObjectRef>(exception));
+}
+
+/*!
+ 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);
+ QScriptValuePrivate* result = new QScriptValuePrivate(this, evaluate(script, file, lineNumber));
+ JSStringRelease(script);
+ JSStringRelease(file);
+ return result;
+}
+
+/*!
+ Evaluates program and returns the result of the evaluation.
+ \internal
+*/
+QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QScriptProgramPrivate* program)
+{
+ if (program->isNull())
+ return new QScriptValuePrivate;
+ return new QScriptValuePrivate(this, evaluate(*program, program->file(), program->line()));
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::uncaughtException() const
+{
+ return m_exception ? new QScriptValuePrivate(this, m_exception) : new QScriptValuePrivate();
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length)
+{
+ // Note that this private data will be deleted in the object finalize function.
+ QNativeFunctionData* data = new QNativeFunctionData(this, fun);
+ JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionClass, reinterpret_cast<void*>(data));
+ QScriptValuePrivate* proto = prototype ? prototype : newObject();
+ return newFunction(funJS, proto);
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
+{
+ // Note that this private data will be deleted in the object finalize function.
+ QNativeFunctionWithArgData* data = new QNativeFunctionWithArgData(this, fun, arg);
+ JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionWithArgClass, reinterpret_cast<void*>(data));
+ QScriptValuePrivate* proto = newObject();
+ return newFunction(funJS, proto);
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newFunction(JSObjectRef funJS, QScriptValuePrivate* prototype)
+{
+ JSObjectSetPrototype(m_context, funJS, m_originalGlobalObject.functionPrototype());
+
+ QScriptValuePrivate* result = new QScriptValuePrivate(this, funJS);
+ static JSStringRef protoName = QScriptConverter::toString("prototype");
+ static JSStringRef constructorName = QScriptConverter::toString("constructor");
+ result->setProperty(protoName, prototype, QScriptValue::Undeletable);
+ prototype->setProperty(constructorName, result, QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
+
+ return result;
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newObject() const
+{
+ return new QScriptValuePrivate(this, JSObjectMake(m_context, /* jsClass */ 0, /* userData */ 0));
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newArray(uint length)
+{
+ JSValueRef exception = 0;
+ JSObjectRef array = JSObjectMakeArray(m_context, /* argumentCount */ 0, /* arguments */ 0, &exception);
+
+ if (!exception) {
+ if (length > 0) {
+ JSRetainPtr<JSStringRef> lengthRef(Adopt, JSStringCreateWithUTF8CString("length"));
+ // array is an Array instance, so an exception should not occure here.
+ JSObjectSetProperty(m_context, array, lengthRef.get(), JSValueMakeNumber(m_context, length), kJSPropertyAttributeNone, /* exception */ 0);
+ }
+ } else {
+ setException(exception, NotNullException);
+ return new QScriptValuePrivate();
+ }
+
+ return new QScriptValuePrivate(this, array);
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newDate(qsreal value)
+{
+ JSValueRef exception = 0;
+ JSValueRef argument = JSValueMakeNumber(m_context, value);
+ JSObjectRef result = JSObjectMakeDate(m_context, /* argumentCount */ 1, &argument, &exception);
+
+ if (exception) {
+ setException(exception, NotNullException);
+ return new QScriptValuePrivate();
+ }
+
+ return new QScriptValuePrivate(this, result);
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::globalObject() const
+{
+ JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
+ return new QScriptValuePrivate(this, globalObject);
+}
diff --git a/Source/JavaScriptCore/qt/api/qscriptengine_p.h b/Source/JavaScriptCore/qt/api/qscriptengine_p.h
new file mode 100644
index 0000000..4603b91
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptengine_p.h
@@ -0,0 +1,259 @@
+/*
+ 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 "qscriptoriginalglobalobject_p.h"
+#include "qscriptstring_p.h"
+#include "qscriptsyntaxcheckresult_p.h"
+#include "qscriptvalue.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <JSBasePrivate.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+
+class QScriptEngine;
+class QScriptSyntaxCheckResultPrivate;
+
+class QScriptEnginePrivate : public QSharedData {
+public:
+ static QScriptEnginePrivate* get(const QScriptEngine* q) { Q_ASSERT(q); return q->d_ptr.data(); }
+ static QScriptEngine* get(const QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_ptr; }
+
+ QScriptEnginePrivate(const QScriptEngine*);
+ ~QScriptEnginePrivate();
+
+ enum SetExceptionFlag {
+ IgnoreNullException = 0x01,
+ NotNullException = 0x02,
+ };
+
+ QScriptSyntaxCheckResultPrivate* checkSyntax(const QString& program);
+ QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber);
+ QScriptValuePrivate* evaluate(const QScriptProgramPrivate* program);
+ inline JSValueRef evaluate(JSStringRef program, JSStringRef fileName, int lineNumber);
+
+ inline bool hasUncaughtException() const;
+ QScriptValuePrivate* uncaughtException() const;
+ inline void clearExceptions();
+ inline void setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags = IgnoreNullException);
+ inline int uncaughtExceptionLineNumber() const;
+ inline QStringList uncaughtExceptionBacktrace() const;
+
+ inline void collectGarbage();
+ inline void reportAdditionalMemoryCost(int cost);
+
+ 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;
+
+ QScriptValuePrivate* newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length);
+ QScriptValuePrivate* newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg);
+ QScriptValuePrivate* newFunction(JSObjectRef funObject, QScriptValuePrivate* prototype);
+
+ QScriptValuePrivate* newObject() const;
+ QScriptValuePrivate* newArray(uint length);
+ QScriptValuePrivate* newDate(qsreal value);
+ QScriptValuePrivate* globalObject() const;
+
+ inline QScriptStringPrivate* toStringHandle(const QString& str) const;
+
+ inline operator JSGlobalContextRef() const;
+
+ inline bool isDate(JSValueRef value) const;
+ inline bool isArray(JSValueRef value) const;
+ inline bool isError(JSValueRef value) const;
+ inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const;
+ inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const;
+
+private:
+ QScriptEngine* q_ptr;
+ JSGlobalContextRef m_context;
+ JSValueRef m_exception;
+
+ QScriptOriginalGlobalObject m_originalGlobalObject;
+
+ JSClassRef m_nativeFunctionClass;
+ JSClassRef m_nativeFunctionWithArgClass;
+};
+
+
+/*!
+ Evaluates given JavaScript program and returns result of the evaluation.
+ \attention this function doesn't take ownership of the parameters.
+ \internal
+*/
+JSValueRef QScriptEnginePrivate::evaluate(JSStringRef program, JSStringRef fileName, int lineNumber)
+{
+ JSValueRef exception;
+ JSValueRef result = JSEvaluateScript(m_context, program, /* Global Object */ 0, fileName, lineNumber, &exception);
+ if (!result) {
+ setException(exception, NotNullException);
+ return exception; // returns an exception
+ }
+ clearExceptions();
+ return result;
+}
+
+bool QScriptEnginePrivate::hasUncaughtException() const
+{
+ return m_exception;
+}
+
+void QScriptEnginePrivate::clearExceptions()
+{
+ if (m_exception)
+ JSValueUnprotect(m_context, m_exception);
+ m_exception = 0;
+}
+
+void QScriptEnginePrivate::setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags)
+{
+ if (!((flags & NotNullException) || exception))
+ return;
+ Q_ASSERT(exception);
+
+ if (m_exception)
+ JSValueUnprotect(m_context, m_exception);
+ JSValueProtect(m_context, exception);
+ m_exception = exception;
+}
+
+int QScriptEnginePrivate::uncaughtExceptionLineNumber() const
+{
+ if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception))
+ return -1;
+
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line"));
+ JSValueRef lineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception);
+ int result = JSValueToNumber(m_context, lineNumber, &exception);
+ return exception ? -1 : result;
+}
+
+QStringList QScriptEnginePrivate::uncaughtExceptionBacktrace() const
+{
+ if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception))
+ return QStringList();
+
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> fileNamePropertyName(Adopt, QScriptConverter::toString("sourceURL"));
+ JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line"));
+ JSValueRef jsFileName = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), fileNamePropertyName.get(), &exception);
+ JSValueRef jsLineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception);
+ JSRetainPtr<JSStringRef> fileName(Adopt, JSValueToStringCopy(m_context, jsFileName, &exception));
+ int lineNumber = JSValueToNumber(m_context, jsLineNumber, &exception);
+ return QStringList(QString::fromLatin1("<anonymous>()@%0:%1")
+ .arg(QScriptConverter::toString(fileName.get()))
+ .arg(QScriptConverter::toString(exception ? -1 : lineNumber)));
+}
+
+void QScriptEnginePrivate::collectGarbage()
+{
+ JSGarbageCollect(m_context);
+}
+
+void QScriptEnginePrivate::reportAdditionalMemoryCost(int cost)
+{
+ if (cost > 0)
+ JSReportExtraMemoryCost(m_context, cost);
+}
+
+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
+{
+ JSStringRef tmp = QScriptConverter::toString(string);
+ JSValueRef result = JSValueMakeString(m_context, tmp);
+ JSStringRelease(tmp);
+ return result;
+}
+
+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);
+}
+
+QScriptStringPrivate* QScriptEnginePrivate::toStringHandle(const QString& str) const
+{
+ return new QScriptStringPrivate(str);
+}
+
+QScriptEnginePrivate::operator JSGlobalContextRef() const
+{
+ Q_ASSERT(this);
+ return m_context;
+}
+
+bool QScriptEnginePrivate::isDate(JSValueRef value) const
+{
+ return m_originalGlobalObject.isDate(value);
+}
+
+bool QScriptEnginePrivate::isArray(JSValueRef value) const
+{
+ return m_originalGlobalObject.isArray(value);
+}
+
+bool QScriptEnginePrivate::isError(JSValueRef value) const
+{
+ return m_originalGlobalObject.isError(value);
+}
+
+inline bool QScriptEnginePrivate::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const
+{
+ // FIXME We need a JSC C API function for this.
+ return m_originalGlobalObject.objectHasOwnProperty(object, property);
+}
+
+inline QVector<JSStringRef> QScriptEnginePrivate::objectGetOwnPropertyNames(JSObjectRef object) const
+{
+ // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties.
+ return m_originalGlobalObject.objectGetOwnPropertyNames(object);
+}
+
+#endif
diff --git a/Source/JavaScriptCore/qt/api/qscriptfunction.cpp b/Source/JavaScriptCore/qt/api/qscriptfunction.cpp
new file mode 100644
index 0000000..9fe37e6
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptfunction.cpp
@@ -0,0 +1,145 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+// Contains the necessary helper structures to make possible expose
+// C/C++ functions to JavaScript environment.
+
+#include "config.h"
+
+#include "qscriptfunction_p.h"
+
+static void qt_NativeFunction_finalize(JSObjectRef object)
+{
+ void* priv = JSObjectGetPrivate(object);
+ delete reinterpret_cast<QNativeFunctionData*>(priv);
+}
+
+static JSValueRef qt_NativeFunction_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ QNativeFunctionData* data = reinterpret_cast<QNativeFunctionData*>(JSObjectGetPrivate(object));
+
+ // TODO: build a QScriptContext and use it in the native call.
+ QScriptContext* scriptContext = 0;
+ Q_UNUSED(context);
+ Q_UNUSED(thisObject);
+ Q_UNUSED(argumentCount);
+ Q_UNUSED(arguments);
+ Q_UNUSED(exception);
+
+ QScriptEnginePrivate* engine = data->engine;
+ QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine)));
+ if (!result->isValid()) {
+ qWarning("Invalid value returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ // Make sure that the result will be assigned to the correct engine.
+ if (!result->engine()) {
+ Q_ASSERT(result->isValid());
+ result->assignEngine(engine);
+ } else if (result->engine() != engine) {
+ qWarning("Value from different engine returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ return *result;
+}
+
+JSClassDefinition qt_NativeFunctionClass = {
+ 0, // version
+ kJSClassAttributeNoAutomaticPrototype, // attributes
+
+ "", // className
+ 0, // parentClass
+
+ 0, // staticValues
+ 0, // staticFunctions
+
+ 0, // initialize
+ qt_NativeFunction_finalize, // finalize
+ 0, // hasProperty
+ 0, // getProperty
+ 0, // setProperty
+ 0, // deleteProperty
+ 0, // getPropertyNames
+ qt_NativeFunction_callAsFunction, // callAsFunction
+ 0, // callAsConstructor
+ 0, // hasInstance
+ 0 // convertToType
+};
+
+static void qt_NativeFunctionWithArg_finalize(JSObjectRef object)
+{
+ void* priv = JSObjectGetPrivate(object);
+ delete reinterpret_cast<QNativeFunctionWithArgData*>(priv);
+}
+
+static JSValueRef qt_NativeFunctionWithArg_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ QNativeFunctionWithArgData* data = reinterpret_cast<QNativeFunctionWithArgData*>(JSObjectGetPrivate(object));
+
+ // TODO: build a QScriptContext and use it in the native call.
+ QScriptContext* scriptContext = 0;
+ Q_UNUSED(context);
+ Q_UNUSED(thisObject);
+ Q_UNUSED(argumentCount);
+ Q_UNUSED(arguments);
+ Q_UNUSED(exception);
+
+ QScriptEnginePrivate* engine = data->engine;
+ QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine), data->arg));
+ if (!result->isValid()) {
+ qWarning("Invalid value returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ // Make sure that the result will be assigned to the correct engine.
+ if (!result->engine()) {
+ Q_ASSERT(result->isValid());
+ result->assignEngine(engine);
+ } else if (result->engine() != engine) {
+ qWarning("Value from different engine returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ return *result;
+}
+
+JSClassDefinition qt_NativeFunctionWithArgClass = {
+ 0, // version
+ kJSClassAttributeNoAutomaticPrototype, // attributes
+
+ "", // className
+ 0, // parentClass
+
+ 0, // staticValues
+ 0, // staticFunctions
+
+ 0, // initialize
+ qt_NativeFunctionWithArg_finalize, // finalize
+ 0, // hasProperty
+ 0, // getProperty
+ 0, // setProperty
+ 0, // deleteProperty
+ 0, // getPropertyNames
+ qt_NativeFunctionWithArg_callAsFunction, // callAsFunction
+ 0, // callAsConstructor
+ 0, // hasInstance
+ 0 // convertToType
+};
diff --git a/Source/JavaScriptCore/qt/api/qscriptfunction_p.h b/Source/JavaScriptCore/qt/api/qscriptfunction_p.h
new file mode 100644
index 0000000..65b6046
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptfunction_p.h
@@ -0,0 +1,57 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptfunction_p_h
+#define qscriptfunction_p_h
+
+#include "config.h"
+
+#include "qscriptengine.h"
+#include "qscriptvalue_p.h"
+
+extern JSClassDefinition qt_NativeFunctionClass;
+extern JSClassDefinition qt_NativeFunctionWithArgClass;
+
+struct QNativeFunctionData
+{
+ QNativeFunctionData(QScriptEnginePrivate* engine, QScriptEngine::FunctionSignature fun)
+ : engine(engine)
+ , fun(fun)
+ {
+ }
+
+ QScriptEnginePrivate* engine;
+ QScriptEngine::FunctionSignature fun;
+};
+
+struct QNativeFunctionWithArgData
+{
+ QNativeFunctionWithArgData(QScriptEnginePrivate* engine, QScriptEngine::FunctionWithArgSignature fun, void* arg)
+ : engine(engine)
+ , fun(fun)
+ , arg(arg)
+ {
+ }
+
+ QScriptEnginePrivate* engine;
+ QScriptEngine::FunctionWithArgSignature fun;
+ void* arg;
+};
+
+#endif
diff --git a/Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
new file mode 100644
index 0000000..2bd945f
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
@@ -0,0 +1,209 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptoriginalglobalobject_p_h
+#define qscriptoriginalglobalobject_p_h
+
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <QtCore/qvector.h>
+
+/*!
+ \internal
+ This class is a workaround for missing JSC C API functionality. This class keeps all important
+ properties of an original (default) global object, so we can use it even if the global object was
+ changed.
+
+ FIXME this class is a container for workarounds :-) it should be replaced by proper JSC C API calls.
+
+ The class have to be created on the QScriptEnginePrivate creation time (before any change got applied to
+ global object).
+*/
+class QScriptOriginalGlobalObject {
+public:
+ inline QScriptOriginalGlobalObject(JSGlobalContextRef context);
+ inline ~QScriptOriginalGlobalObject();
+
+ inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const;
+ inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const;
+
+ inline bool isDate(JSValueRef value) const;
+ inline bool isArray(JSValueRef value) const;
+ inline bool isError(JSValueRef value) const;
+
+ inline JSValueRef functionPrototype() const;
+private:
+ inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const;
+ inline void initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype);
+
+ // Copy of the global context reference (the same as in QScriptEnginePrivate).
+ JSGlobalContextRef m_context;
+
+ // Copy of constructors and prototypes used in isType functions.
+ JSObjectRef m_arrayConstructor;
+ JSValueRef m_arrayPrototype;
+ JSObjectRef m_errorConstructor;
+ JSValueRef m_errorPrototype;
+ JSObjectRef m_functionConstructor;
+ JSValueRef m_functionPrototype;
+ JSObjectRef m_dateConstructor;
+ JSValueRef m_datePrototype;
+
+ // Reference to standard JS functions that are not exposed by JSC C API.
+ JSObjectRef m_hasOwnPropertyFunction;
+ JSObjectRef m_getOwnPropertyNamesFunction;
+};
+
+QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef context)
+ : m_context(JSGlobalContextRetain(context))
+{
+ JSObjectRef globalObject = JSContextGetGlobalObject(m_context);
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> propertyName;
+
+ propertyName.adopt(JSStringCreateWithUTF8CString("prototype"));
+ initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype);
+ initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype);
+ initializeMember(globalObject, propertyName.get(), "Function", m_functionConstructor, m_functionPrototype);
+ initializeMember(globalObject, propertyName.get(), "Date", m_dateConstructor, m_datePrototype);
+
+ propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty"));
+ m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception));
+ JSValueProtect(m_context, m_hasOwnPropertyFunction);
+ Q_ASSERT(JSValueIsObject(m_context, m_hasOwnPropertyFunction));
+ Q_ASSERT(JSObjectIsFunction(m_context, m_hasOwnPropertyFunction));
+ Q_ASSERT(!exception);
+
+ propertyName.adopt(JSStringCreateWithUTF8CString("Object"));
+ JSObjectRef objectConstructor
+ = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception));
+ propertyName.adopt(JSStringCreateWithUTF8CString("getOwnPropertyNames"));
+ m_getOwnPropertyNamesFunction
+ = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, objectConstructor, propertyName.get(), &exception));
+ JSValueProtect(m_context, m_getOwnPropertyNamesFunction);
+ Q_ASSERT(JSValueIsObject(m_context, m_getOwnPropertyNamesFunction));
+ Q_ASSERT(JSObjectIsFunction(m_context, m_getOwnPropertyNamesFunction));
+ Q_ASSERT(!exception);
+}
+
+inline void QScriptOriginalGlobalObject::initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype)
+{
+ JSRetainPtr<JSStringRef> typeName(Adopt, JSStringCreateWithUTF8CString(type));
+ JSValueRef exception = 0;
+
+ // Save references to the Type constructor and prototype.
+ JSValueRef typeConstructor = JSObjectGetProperty(m_context, globalObject, typeName.get(), &exception);
+ Q_ASSERT(JSValueIsObject(m_context, typeConstructor));
+ constructor = JSValueToObject(m_context, typeConstructor, &exception);
+ JSValueProtect(m_context, constructor);
+
+ // Note that this is not the [[Prototype]] internal property (which we could
+ // get via JSObjectGetPrototype), but the Type.prototype, that will be set
+ // as [[Prototype]] of Type instances.
+ prototype = JSObjectGetProperty(m_context, constructor, prototypeName, &exception);
+ Q_ASSERT(JSValueIsObject(m_context, prototype));
+ JSValueProtect(m_context, prototype);
+ Q_ASSERT(!exception);
+}
+
+QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject()
+{
+ JSValueUnprotect(m_context, m_arrayConstructor);
+ JSValueUnprotect(m_context, m_arrayPrototype);
+ JSValueUnprotect(m_context, m_errorConstructor);
+ JSValueUnprotect(m_context, m_errorPrototype);
+ JSValueUnprotect(m_context, m_functionConstructor);
+ JSValueUnprotect(m_context, m_functionPrototype);
+ JSValueUnprotect(m_context, m_dateConstructor);
+ JSValueUnprotect(m_context, m_datePrototype);
+ JSValueUnprotect(m_context, m_hasOwnPropertyFunction);
+ JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction);
+ JSGlobalContextRelease(m_context);
+}
+
+inline bool QScriptOriginalGlobalObject::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const
+{
+ // FIXME This function should be replaced by JSC C API.
+ JSValueRef exception = 0;
+ JSValueRef propertyName[] = { JSValueMakeString(m_context, property) };
+ JSValueRef result = JSObjectCallAsFunction(m_context, m_hasOwnPropertyFunction, object, 1, propertyName, &exception);
+ return exception ? false : JSValueToBoolean(m_context, result);
+}
+
+/*!
+ \internal
+ This method gives ownership of all JSStringRefs.
+*/
+inline QVector<JSStringRef> QScriptOriginalGlobalObject::objectGetOwnPropertyNames(JSObjectRef object) const
+{
+ JSValueRef exception = 0;
+ JSObjectRef propertyNames
+ = const_cast<JSObjectRef>(JSObjectCallAsFunction(m_context,
+ m_getOwnPropertyNamesFunction,
+ /* thisObject */ 0,
+ /* argumentCount */ 1,
+ &object,
+ &exception));
+ Q_ASSERT(JSValueIsObject(m_context, propertyNames));
+ Q_ASSERT(!exception);
+ JSStringRef lengthName = QScriptConverter::toString("length");
+ int count = JSValueToNumber(m_context, JSObjectGetProperty(m_context, propertyNames, lengthName, &exception), &exception);
+
+ Q_ASSERT(!exception);
+ QVector<JSStringRef> names;
+ names.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ JSValueRef tmp = JSObjectGetPropertyAtIndex(m_context, propertyNames, i, &exception);
+ names.append(JSValueToStringCopy(m_context, tmp, &exception));
+ Q_ASSERT(!exception);
+ }
+ return names;
+}
+
+inline bool QScriptOriginalGlobalObject::isDate(JSValueRef value) const
+{
+ return isType(value, m_dateConstructor, m_datePrototype);
+}
+
+inline bool QScriptOriginalGlobalObject::isArray(JSValueRef value) const
+{
+ return isType(value, m_arrayConstructor, m_arrayPrototype);
+}
+
+inline bool QScriptOriginalGlobalObject::isError(JSValueRef value) const
+{
+ return isType(value, m_errorConstructor, m_errorPrototype);
+}
+
+inline JSValueRef QScriptOriginalGlobalObject::functionPrototype() const
+{
+ return m_functionPrototype;
+}
+
+inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const
+{
+ // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value
+ // is an object of the Type if it was created with the Type constructor or if it is the Type.prototype.
+ JSValueRef exception = 0;
+ bool result = JSValueIsInstanceOfConstructor(m_context, value, constructor, &exception) || JSValueIsStrictEqual(m_context, value, prototype);
+ Q_ASSERT(!exception);
+ return result;
+}
+
+#endif // qscriptoriginalglobalobject_p_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptprogram.cpp b/Source/JavaScriptCore/qt/api/qscriptprogram.cpp
new file mode 100644
index 0000000..d7d4948
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptprogram.cpp
@@ -0,0 +1,136 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#include "qscriptprogram.h"
+
+#include "qscriptprogram_p.h"
+
+/*!
+ \internal
+
+ \class QScriptProgram
+
+ \brief The QScriptProgram class encapsulates a Qt Script program.
+
+ \ingroup script
+
+ QScriptProgram retains the compiled representation of the script if
+ possible. Thus, QScriptProgram can be used to evaluate the same
+ script multiple times more efficiently.
+
+ \code
+ QScriptEngine engine;
+ QScriptProgram program("1 + 2");
+ QScriptValue result = engine.evaluate(program);
+ \endcode
+*/
+
+/*!
+ Constructs a null QScriptProgram.
+*/
+QScriptProgram::QScriptProgram()
+ : d_ptr(new QScriptProgramPrivate)
+{}
+
+/*!
+ Constructs a new QScriptProgram with the given \a sourceCode, \a
+ fileName and \a firstLineNumber.
+*/
+QScriptProgram::QScriptProgram(const QString& sourceCode,
+ const QString fileName,
+ int firstLineNumber)
+ : d_ptr(new QScriptProgramPrivate(sourceCode, fileName, firstLineNumber))
+{}
+
+/*!
+ Destroys this QScriptProgram.
+*/
+QScriptProgram::~QScriptProgram()
+{}
+
+/*!
+ Constructs a new QScriptProgram that is a copy of \a other.
+*/
+QScriptProgram::QScriptProgram(const QScriptProgram& other)
+{
+ d_ptr = other.d_ptr;
+}
+
+/*!
+ Assigns the \a other value to this QScriptProgram.
+*/
+QScriptProgram& QScriptProgram::operator=(const QScriptProgram& other)
+{
+ d_ptr = other.d_ptr;
+ return *this;
+}
+
+/*!
+ Returns true if this QScriptProgram is null; otherwise
+ returns false.
+*/
+bool QScriptProgram::isNull() const
+{
+ return d_ptr->isNull();
+}
+
+/*!
+ Returns the source code of this program.
+*/
+QString QScriptProgram::sourceCode() const
+{
+ return d_ptr->sourceCode();
+}
+
+/*!
+ Returns the filename associated with this program.
+*/
+QString QScriptProgram::fileName() const
+{
+ return d_ptr->fileName();
+}
+
+/*!
+ Returns the line number associated with this program.
+*/
+int QScriptProgram::firstLineNumber() const
+{
+ return d_ptr->firstLineNumber();
+}
+
+/*!
+ Returns true if this QScriptProgram is equal to \a other;
+ otherwise returns false.
+*/
+bool QScriptProgram::operator==(const QScriptProgram& other) const
+{
+ return d_ptr == other.d_ptr || *d_ptr == *other.d_ptr;
+}
+
+/*!
+ Returns true if this QScriptProgram is not equal to \a other;
+ otherwise returns false.
+*/
+bool QScriptProgram::operator!=(const QScriptProgram& other) const
+{
+ return d_ptr != other.d_ptr && *d_ptr != *other.d_ptr;
+}
+
diff --git a/Source/JavaScriptCore/qt/api/qscriptprogram.h b/Source/JavaScriptCore/qt/api/qscriptprogram.h
new file mode 100644
index 0000000..93c8a3c
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptprogram.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptprogram_h
+#define qscriptprogram_h
+
+#include "qtscriptglobal.h"
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QScriptProgramPrivate;
+class Q_JAVASCRIPT_EXPORT QScriptProgram {
+public:
+ QScriptProgram();
+ QScriptProgram(const QString& sourceCode,
+ const QString fileName = QString(),
+ int firstLineNumber = 1);
+ QScriptProgram(const QScriptProgram& other);
+ ~QScriptProgram();
+
+ QScriptProgram& operator=(const QScriptProgram& other);
+
+ bool isNull() const;
+
+ QString sourceCode() const;
+ QString fileName() const;
+ int firstLineNumber() const;
+
+ bool operator==(const QScriptProgram& other) const;
+ bool operator!=(const QScriptProgram& other) const;
+
+private:
+ QExplicitlySharedDataPointer<QScriptProgramPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QScriptProgram)
+};
+
+#endif // qscriptprogram_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptprogram_p.h b/Source/JavaScriptCore/qt/api/qscriptprogram_p.h
new file mode 100644
index 0000000..f6882c5
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptprogram_p.h
@@ -0,0 +1,133 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptprogram_p_h
+#define qscriptprogram_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptprogram.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+/*
+ FIXME The QScriptProgramPrivate potentially could be much faster. In current implementation we
+ gain CPU time only by avoiding QString -> JSStringRef conversion. In the ideal world we should
+ have a function inside the JSC C API that could provide us "parse once, execute multiple times"
+ functionality.
+*/
+
+class QScriptProgramPrivate : public QSharedData {
+public:
+ inline static QScriptProgramPrivate* get(const QScriptProgram& program);
+ inline QScriptProgramPrivate();
+ inline QScriptProgramPrivate(const QString& sourceCode,
+ const QString fileName,
+ int firstLineNumber);
+
+ inline ~QScriptProgramPrivate();
+
+ inline bool isNull() const;
+
+ inline QString sourceCode() const;
+ inline QString fileName() const;
+ inline int firstLineNumber() const;
+
+ inline bool operator==(const QScriptProgramPrivate& other) const;
+ inline bool operator!=(const QScriptProgramPrivate& other) const;
+
+ inline operator JSStringRef() const;
+ inline JSStringRef file() const;
+ inline int line() const;
+private:
+ JSStringRef m_program;
+ JSStringRef m_fileName;
+ int m_line;
+};
+
+QScriptProgramPrivate* QScriptProgramPrivate::get(const QScriptProgram& program)
+{
+ return const_cast<QScriptProgramPrivate*>(program.d_ptr.constData());
+}
+
+QScriptProgramPrivate::QScriptProgramPrivate()
+ : m_program(0)
+ , m_fileName(0)
+ , m_line(-1)
+{}
+
+QScriptProgramPrivate::QScriptProgramPrivate(const QString& sourceCode,
+ const QString fileName,
+ int firstLineNumber)
+ : m_program(QScriptConverter::toString(sourceCode))
+ , m_fileName(QScriptConverter::toString(fileName))
+ , m_line(firstLineNumber)
+{}
+
+QScriptProgramPrivate::~QScriptProgramPrivate()
+{
+ if (!isNull()) {
+ JSStringRelease(m_program);
+ JSStringRelease(m_fileName);
+ }
+}
+
+bool QScriptProgramPrivate::isNull() const
+{
+ return !m_program;
+}
+
+QString QScriptProgramPrivate::sourceCode() const
+{
+ return QScriptConverter::toString(m_program);
+}
+
+QString QScriptProgramPrivate::fileName() const
+{
+ return QScriptConverter::toString(m_fileName);
+}
+
+int QScriptProgramPrivate::firstLineNumber() const
+{
+ return m_line;
+}
+
+bool QScriptProgramPrivate::operator==(const QScriptProgramPrivate& other) const
+{
+ return m_line == other.m_line
+ && JSStringIsEqual(m_fileName, other.m_fileName)
+ && JSStringIsEqual(m_program, other.m_program);
+}
+
+bool QScriptProgramPrivate::operator!=(const QScriptProgramPrivate& other) const
+{
+ return m_line != other.m_line
+ || !JSStringIsEqual(m_fileName, other.m_fileName)
+ || !JSStringIsEqual(m_program, other.m_program);
+}
+
+QScriptProgramPrivate::operator JSStringRef() const
+{
+ return m_program;
+}
+
+JSStringRef QScriptProgramPrivate::file() const {return m_fileName; }
+int QScriptProgramPrivate::line() const { return m_line; }
+
+#endif // qscriptprogram_p_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptstring.cpp b/Source/JavaScriptCore/qt/api/qscriptstring.cpp
new file mode 100644
index 0000000..83c03c5
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptstring.cpp
@@ -0,0 +1,131 @@
+/*
+ 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 "qscriptstring.h"
+
+#include "qscriptstring_p.h"
+#include <QtCore/qhash.h>
+
+/*!
+ Constructs an invalid QScriptString.
+*/
+QScriptString::QScriptString()
+ : d_ptr(new QScriptStringPrivate())
+{
+}
+/*!
+ Constructs an QScriptString from internal representation
+ \internal
+*/
+QScriptString::QScriptString(QScriptStringPrivate* d)
+ : d_ptr(d)
+{
+}
+
+/*!
+ Constructs a new QScriptString that is a copy of \a other.
+*/
+QScriptString::QScriptString(const QScriptString& other)
+{
+ d_ptr = other.d_ptr;
+}
+
+/*!
+ Destroys this QScriptString.
+*/
+QScriptString::~QScriptString()
+{
+}
+
+/*!
+ Assigns the \a other value to this QScriptString.
+*/
+QScriptString& QScriptString::operator=(const QScriptString& other)
+{
+ d_ptr = other.d_ptr;
+ return *this;
+}
+
+/*!
+ Returns true if this QScriptString is valid; otherwise
+ returns false.
+*/
+bool QScriptString::isValid() const
+{
+ return d_ptr->isValid();
+}
+
+/*!
+ Returns true if this QScriptString is equal to \a other;
+ otherwise returns false.
+*/
+bool QScriptString::operator==(const QScriptString& other) const
+{
+ return d_ptr == other.d_ptr || *d_ptr == *(other.d_ptr);
+}
+
+/*!
+ Returns true if this QScriptString is not equal to \a other;
+ otherwise returns false.
+*/
+bool QScriptString::operator!=(const QScriptString& other) const
+{
+ return d_ptr != other.d_ptr || *d_ptr != *(other.d_ptr);
+}
+
+/*!
+ Attempts to convert this QScriptString to a QtScript array index,
+ and returns the result.
+
+ If a conversion error occurs, *\a{ok} is set to false; otherwise
+ *\a{ok} is set to true.
+*/
+quint32 QScriptString::toArrayIndex(bool* ok) const
+{
+ return d_ptr->toArrayIndex(ok);
+}
+
+/*!
+ Returns the string that this QScriptString represents, or a
+ null string if this QScriptString is not valid.
+
+ \sa isValid()
+*/
+QString QScriptString::toString() const
+{
+ return d_ptr->toString();
+}
+
+/*!
+ Returns the string that this QScriptString represents, or a
+ null string if this QScriptString is not valid.
+
+ \sa toString()
+*/
+QScriptString::operator QString() const
+{
+ return d_ptr->toString();
+}
+
+uint qHash(const QScriptString& key)
+{
+ return qHash(QScriptStringPrivate::get(key)->id());
+}
diff --git a/Source/JavaScriptCore/qt/api/qscriptstring.h b/Source/JavaScriptCore/qt/api/qscriptstring.h
new file mode 100644
index 0000000..16593bc
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptstring.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptstring_h
+#define qscriptstring_h
+
+#include "qtscriptglobal.h"
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QScriptStringPrivate;
+typedef QExplicitlySharedDataPointer<QScriptStringPrivate> QScriptStringPtr;
+
+class Q_JAVASCRIPT_EXPORT QScriptString {
+public:
+ QScriptString();
+ QScriptString(const QScriptString& other);
+ ~QScriptString();
+
+ QScriptString& operator=(const QScriptString& other);
+
+ bool isValid() const;
+
+ bool operator==(const QScriptString& other) const;
+ bool operator!=(const QScriptString& other) const;
+
+ quint32 toArrayIndex(bool* ok = 0) const;
+
+ QString toString() const;
+ operator QString() const;
+
+private:
+ QScriptString(QScriptStringPrivate* d);
+
+ QScriptStringPtr d_ptr;
+
+ friend class QScriptStringPrivate;
+};
+
+uint qHash(const QScriptString& key);
+
+#endif // qscriptstring_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptstring_p.h b/Source/JavaScriptCore/qt/api/qscriptstring_p.h
new file mode 100644
index 0000000..fe84f4d
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptstring_p.h
@@ -0,0 +1,124 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptstring_p_h
+#define qscriptstring_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptstring.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptStringPrivate : public QSharedData {
+public:
+ inline QScriptStringPrivate();
+ inline QScriptStringPrivate(const QString& qtstring);
+ inline ~QScriptStringPrivate();
+
+ static inline QScriptString get(QScriptStringPrivate* d);
+ static inline QScriptStringPtr get(const QScriptString& p);
+
+ inline bool isValid() const;
+
+ inline bool operator==(const QScriptStringPrivate& other) const;
+ inline bool operator!=(const QScriptStringPrivate& other) const;
+
+ inline quint32 toArrayIndex(bool* ok = 0) const;
+
+ inline QString toString() const;
+
+ inline quint64 id() const;
+
+ inline operator JSStringRef() const;
+
+private:
+ JSStringRef m_string;
+};
+
+
+QScriptStringPrivate::QScriptStringPrivate()
+ : m_string(0)
+{}
+
+QScriptStringPrivate::QScriptStringPrivate(const QString& qtstring)
+ : m_string(QScriptConverter::toString(qtstring))
+{}
+
+QScriptStringPrivate::~QScriptStringPrivate()
+{
+ if (isValid())
+ JSStringRelease(m_string);
+}
+
+QScriptString QScriptStringPrivate::get(QScriptStringPrivate* d)
+{
+ Q_ASSERT(d);
+ return QScriptString(d);
+}
+
+QScriptStringPtr QScriptStringPrivate::get(const QScriptString& p)
+{
+ return p.d_ptr;
+}
+
+bool QScriptStringPrivate::isValid() const
+{
+ return m_string;
+}
+
+bool QScriptStringPrivate::operator==(const QScriptStringPrivate& other) const
+{
+ return isValid() && other.isValid() && JSStringIsEqual(m_string, other.m_string);
+}
+
+bool QScriptStringPrivate::operator!=(const QScriptStringPrivate& other) const
+{
+ return isValid() && other.isValid() && !JSStringIsEqual(m_string, other.m_string);
+}
+
+quint32 QScriptStringPrivate::toArrayIndex(bool* ok) const
+{
+ quint32 idx = QScriptConverter::toArrayIndex(m_string);
+ if (ok)
+ *ok = (idx != 0xffffffff);
+ return idx;
+}
+
+QString QScriptStringPrivate::toString() const
+{
+ return QScriptConverter::toString(m_string);
+}
+
+quint64 QScriptStringPrivate::id() const
+{
+ return reinterpret_cast<quint32>(m_string);
+}
+
+/*!
+ \internal
+ This method should be used for invoking JSC functions.
+ \note This method keeps ownership of an internal JSStringRef.
+*/
+QScriptStringPrivate::operator JSStringRef() const
+{
+ return m_string;
+}
+
+#endif // qscriptstring_p_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp
new file mode 100644
index 0000000..3948c5d
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp
@@ -0,0 +1,148 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#include "qscriptsyntaxcheckresult.h"
+#include "qscriptsyntaxcheckresult_p.h"
+
+/*!
+ \class QScriptSyntaxCheckResult
+
+ \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check.
+
+ \ingroup script
+ \mainclass
+
+ QScriptSyntaxCheckResult is returned by QScriptEngine::checkSyntax() to
+ provide information about the syntactical (in)correctness of a script.
+*/
+
+/*!
+ \enum QScriptSyntaxCheckResult::State
+
+ This enum specifies the state of a syntax check.
+
+ \value Error The program contains a syntax error.
+ \value Intermediate The program is incomplete.
+ \value Valid The program is a syntactically correct Qt Script program.
+*/
+
+/*!
+ Constructs a new QScriptSyntaxCheckResult from the \a other result.
+*/
+QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult& other)
+ : d_ptr(other.d_ptr)
+{}
+
+/*!
+ Constructs a new QScriptSyntaxCheckResult from an internal representation.
+ \internal
+*/
+QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate* d)
+ : d_ptr(d)
+{}
+
+/*!
+ Destroys this QScriptSyntaxCheckResult.
+*/
+QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult()
+{}
+
+/*!
+ Assigns the \a other result to this QScriptSyntaxCheckResult, and returns a
+ reference to this QScriptSyntaxCheckResult.
+*/
+QScriptSyntaxCheckResult& QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult& other)
+{
+ d_ptr = other.d_ptr;
+ return *this;
+}
+
+/*!
+ Returns the state of this QScriptSyntaxCheckResult.
+*/
+QScriptSyntaxCheckResult::State QScriptSyntaxCheckResult::state() const
+{
+ return d_ptr->state();
+}
+
+/*!
+ Returns the error line number of this QScriptSyntaxCheckResult, or -1 if
+ there is no error.
+
+ \sa state(), errorMessage()
+*/
+int QScriptSyntaxCheckResult::errorLineNumber() const
+{
+ return d_ptr->errorLineNumber();
+}
+
+/*!
+ Returns the error column number of this QScriptSyntaxCheckResult, or -1 if
+ there is no error.
+
+ \sa state(), errorLineNumber()
+*/
+int QScriptSyntaxCheckResult::errorColumnNumber() const
+{
+ return d_ptr->errorColumnNumber();
+}
+
+/*!
+ Returns the error message of this QScriptSyntaxCheckResult, or an empty
+ string if there is no error.
+
+ \sa state(), errorLineNumber()
+*/
+QString QScriptSyntaxCheckResult::errorMessage() const
+{
+ return d_ptr->errorMessage();
+}
+
+QScriptSyntaxCheckResultPrivate::~QScriptSyntaxCheckResultPrivate()
+{
+ if (m_exception)
+ JSValueUnprotect(*m_engine, m_exception);
+}
+
+QString QScriptSyntaxCheckResultPrivate::errorMessage() const
+{
+ if (!m_exception)
+ return QString();
+
+ JSStringRef tmp = JSValueToStringCopy(*m_engine, m_exception, /* exception */ 0);
+ QString message = QScriptConverter::toString(tmp);
+ JSStringRelease(tmp);
+ return message;
+}
+
+int QScriptSyntaxCheckResultPrivate::errorLineNumber() const
+{
+ if (!m_exception)
+ return -1;
+ // m_exception is an instance of the Exception so it has "line" attribute.
+ JSStringRef lineAttrName = QScriptConverter::toString("line");
+ JSValueRef line = JSObjectGetProperty(*m_engine,
+ m_exception,
+ lineAttrName,
+ /* exceptions */0);
+ JSStringRelease(lineAttrName);
+ return JSValueToNumber(*m_engine, line, /* exceptions */0);
+}
diff --git a/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h
new file mode 100644
index 0000000..aa57744
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptsyntaxcheckresult_h
+#define qscriptsyntaxcheckresult_h
+
+#include "qtscriptglobal.h"
+#include <QtCore/qshareddata.h>
+
+class QScriptSyntaxCheckResultPrivate;
+class Q_JAVASCRIPT_EXPORT QScriptSyntaxCheckResult {
+public:
+ enum State {
+ Error,
+ Intermediate,
+ Valid
+ };
+
+ QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult& other);
+ ~QScriptSyntaxCheckResult();
+ QScriptSyntaxCheckResult& operator=(const QScriptSyntaxCheckResult& other);
+
+ State state() const;
+ int errorLineNumber() const;
+ int errorColumnNumber() const;
+ QString errorMessage() const;
+
+private:
+ QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate* d);
+ QExplicitlySharedDataPointer<QScriptSyntaxCheckResultPrivate> d_ptr;
+
+ friend class QScriptSyntaxCheckResultPrivate;
+};
+#endif // qscriptsyntaxcheckresult_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h
new file mode 100644
index 0000000..6e1a131
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptsyntaxcheckresult_p_h
+#define qscriptsyntaxcheckresult_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptengine_p.h"
+#include "qscriptsyntaxcheckresult.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptSyntaxCheckResultPrivate : public QSharedData {
+public:
+ static inline QScriptSyntaxCheckResult get(QScriptSyntaxCheckResultPrivate* p);
+ inline QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine);
+ inline QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine, JSObjectRef value);
+ ~QScriptSyntaxCheckResultPrivate();
+
+ inline QScriptSyntaxCheckResult::State state() const;
+ int errorLineNumber() const;
+ inline int errorColumnNumber() const;
+ QString errorMessage() const;
+private:
+ JSObjectRef m_exception;
+ QScriptEnginePtr m_engine;
+};
+
+QScriptSyntaxCheckResult QScriptSyntaxCheckResultPrivate::get(QScriptSyntaxCheckResultPrivate* p)
+{
+ return QScriptSyntaxCheckResult(p);
+}
+
+QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine)
+ : m_exception(0)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+{}
+
+QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine, JSObjectRef value)
+ : m_exception(value)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+{}
+
+QScriptSyntaxCheckResult::State QScriptSyntaxCheckResultPrivate::state() const
+{
+ // FIXME This function doesn't return QScriptSyntaxCheckResult::Intermediate
+ return m_exception ? QScriptSyntaxCheckResult::Error : QScriptSyntaxCheckResult::Valid;
+}
+
+int QScriptSyntaxCheckResultPrivate::errorColumnNumber() const
+{
+ // FIXME JSC C API doesn't expose the error column number.
+ return m_exception ? 1 : -1;
+}
+
+
+#endif // qscriptsyntaxcheckresult_p_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptvalue.cpp b/Source/JavaScriptCore/qt/api/qscriptvalue.cpp
new file mode 100644
index 0000000..8a7a6c4
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptvalue.cpp
@@ -0,0 +1,802 @@
+/*
+ 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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ else
+ d_ptr = new QScriptValuePrivate(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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ else
+ d_ptr = new QScriptValuePrivate(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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ else
+ d_ptr = new QScriptValuePrivate(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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ else
+ d_ptr = new QScriptValuePrivate(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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ else
+ d_ptr = new QScriptValuePrivate(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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), QString::fromUtf8(value));
+ else
+ d_ptr = new QScriptValuePrivate(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)
+{
+ if (engine)
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ else
+ d_ptr = new QScriptValuePrivate(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 an object of the Array class;
+ otherwise returns false.
+
+ \sa QScriptEngine::newArray()
+*/
+bool QScriptValue::isArray() const
+{
+ return d_ptr->isArray();
+}
+
+/*!
+ Returns true if this QScriptValue is an object of the Date class;
+ otherwise returns false.
+
+ \sa QScriptEngine::newDate()
+*/
+bool QScriptValue::isDate() const
+{
+ return d_ptr->isDate();
+}
+
+/*!
+ 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();
+}
+
+/*!
+ \obsolete
+
+ This function is obsolete; use QScriptEngine::toObject() instead.
+*/
+QScriptValue QScriptValue::toObject() const
+{
+ return QScriptValuePrivate::get(d_ptr->toObject());
+}
+
+/*!
+ Returns a QDateTime representation of this value, in local time.
+ If this QScriptValue is not a date, or the value of the date is
+ NaN (Not-a-Number), an invalid QDateTime is returned.
+
+ \sa isDate()
+*/
+QDateTime QScriptValue::toDateTime() const
+{
+ return d_ptr->toDateTime();
+}
+
+/*!
+ 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;
+}
+
+/*!
+ If this QScriptValue is an object, returns the internal prototype
+ (\c{__proto__} property) of this object; otherwise returns an
+ invalid QScriptValue.
+
+ \sa setPrototype(), isObject()
+*/
+QScriptValue QScriptValue::prototype() const
+{
+ return QScriptValuePrivate::get(d_ptr->prototype());
+}
+
+/*!
+ If this QScriptValue is an object, sets the internal prototype
+ (\c{__proto__} property) of this object to be \a prototype;
+ otherwise does nothing.
+
+ The internal prototype should not be confused with the public
+ property with name "prototype"; the public prototype is usually
+ only set on functions that act as constructors.
+
+ \sa prototype(), isObject()
+*/
+void QScriptValue::setPrototype(const QScriptValue& prototype)
+{
+ d_ptr->setPrototype(QScriptValuePrivate::get(prototype));
+}
+
+/*!
+ 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->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->strictlyEquals(QScriptValuePrivate::get(other));
+}
+
+/*!
+ Returns true if this QScriptValue is an instance of
+ \a other; otherwise returns false.
+
+ This QScriptValue is considered to be an instance of \a other if
+ \a other is a function and the value of the \c{prototype}
+ property of \a other is in the prototype chain of this
+ QScriptValue.
+*/
+bool QScriptValue::instanceOf(const QScriptValue& other) const
+{
+ return d_ptr->instanceOf(QScriptValuePrivate::get(other));
+}
+
+/*!
+ Returns the value of this QScriptValue's property with the given \a name,
+ using the given \a mode to resolve the property.
+
+ If no such property exists, an invalid QScriptValue is returned.
+
+ If the property is implemented using a getter function (i.e. has the
+ PropertyGetter flag set), calling property() has side-effects on the
+ script engine, since the getter function will be called (possibly
+ resulting in an uncaught script exception). If an exception
+ occurred, property() returns the value that was thrown (typically
+ an \c{Error} object).
+
+ \sa setProperty(), propertyFlags(), QScriptValueIterator
+*/
+QScriptValue QScriptValue::property(const QString& name, const ResolveFlags& mode) const
+{
+ return QScriptValuePrivate::get(d_ptr->property(name, mode));
+}
+
+/*!
+ \overload
+
+ Returns the value of this QScriptValue's property with the given \a name,
+ using the given \a mode to resolve the property.
+
+ This overload of property() is useful when you need to look up the
+ same property repeatedly, since the lookup can be performed faster
+ when the name is represented as an interned string.
+
+ \sa QScriptEngine::toStringHandle(), setProperty()
+*/
+QScriptValue QScriptValue::property(const QScriptString& name, const ResolveFlags& mode) const
+{
+ return QScriptValuePrivate::get(d_ptr->property(QScriptStringPrivate::get(name).constData(), mode));
+}
+
+/*!
+ \overload
+
+ Returns the property at the given \a arrayIndex, using the given \a
+ mode to resolve the property.
+
+ This function is provided for convenience and performance when
+ working with array objects.
+
+ If this QScriptValue is not an Array object, this function behaves
+ as if property() was called with the string representation of \a
+ arrayIndex.
+*/
+QScriptValue QScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode) const
+{
+ return QScriptValuePrivate::get(d_ptr->property(arrayIndex, mode));
+}
+
+/*!
+ Sets the value of this QScriptValue's property with the given \a name to
+ the given \a value.
+
+ If this QScriptValue is not an object, this function does nothing.
+
+ If this QScriptValue does not already have a property with name \a name,
+ a new property is created; the given \a flags then specify how this
+ property may be accessed by script code.
+
+ If \a value is invalid, the property is removed.
+
+ If the property is implemented using a setter function (i.e. has the
+ PropertySetter flag set), calling setProperty() has side-effects on
+ the script engine, since the setter function will be called with the
+ given \a value as argument (possibly resulting in an uncaught script
+ exception).
+
+ Note that you cannot specify custom getter or setter functions for
+ built-in properties, such as the \c{length} property of Array objects
+ or meta properties of QObject objects.
+
+ \sa property()
+*/
+void QScriptValue::setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags)
+{
+ d_ptr->setProperty(name, QScriptValuePrivate::get(value), flags);
+}
+
+/*!
+ \overload
+
+ Sets the property at the given \a arrayIndex to the given \a value.
+
+ This function is provided for convenience and performance when
+ working with array objects.
+
+ If this QScriptValue is not an Array object, this function behaves
+ as if setProperty() was called with the string representation of \a
+ arrayIndex.
+*/
+void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags)
+{
+ d_ptr->setProperty(arrayIndex, QScriptValuePrivate::get(value), flags);
+}
+
+/*!
+ Sets the value of this QScriptValue's property with the given \a
+ name to the given \a value. The given \a flags specify how this
+ property may be accessed by script code.
+
+ This overload of setProperty() is useful when you need to set the
+ same property repeatedly, since the operation can be performed
+ faster when the name is represented as an interned string.
+
+ \sa QScriptEngine::toStringHandle()
+*/
+void QScriptValue::setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags)
+{
+ d_ptr->setProperty(QScriptStringPrivate::get(name).constData(), QScriptValuePrivate::get(value), flags);
+}
+
+/*!
+ Returns the flags of the property with the given \a name, using the
+ given \a mode to resolve the property.
+
+ \sa property()
+*/
+QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString& name, const ResolveFlags& mode) const
+{
+ return d_ptr->propertyFlags(name, mode);
+}
+
+/*!
+ Returns the flags of the property with the given \a name, using the
+ given \a mode to resolve the property.
+
+ \sa property()
+*/
+QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString& name, const ResolveFlags& mode) const
+{
+ return d_ptr->propertyFlags(QScriptStringPrivate::get(name).constData(), mode);
+}
diff --git a/Source/JavaScriptCore/qt/api/qscriptvalue.h b/Source/JavaScriptCore/qt/api/qscriptvalue.h
new file mode 100644
index 0000000..bd33849
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptvalue.h
@@ -0,0 +1,140 @@
+/*
+ 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 "qscriptstring.h"
+#include <QtCore/qlist.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptEngine;
+class QScriptValuePrivate;
+class QDateTime;
+
+class QScriptValue;
+typedef QList<QScriptValue> QScriptValueList;
+
+typedef double qsreal;
+
+class QScriptValue {
+public:
+ enum ResolveFlag {
+ ResolveLocal = 0x00,
+ ResolvePrototype = 0x01,
+ ResolveScope = 0x02,
+ ResolveFull = ResolvePrototype | ResolveScope
+ };
+ Q_DECLARE_FLAGS(ResolveFlags, ResolveFlag)
+
+ enum PropertyFlag {
+ ReadOnly = 0x00000001,
+ Undeletable = 0x00000002,
+ SkipInEnumeration = 0x00000004,
+ PropertyGetter = 0x00000008,
+ PropertySetter = 0x00000010,
+ QObjectMember = 0x00000020,
+ KeepExistingFlags = 0x00000800,
+ UserRange = 0xff000000 // Users may use these as they see fit.
+ };
+ Q_DECLARE_FLAGS(PropertyFlags, PropertyFlag)
+
+ 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);
+
+ QScriptValue prototype() const;
+ void setPrototype(const QScriptValue& prototype);
+
+ bool equals(const QScriptValue& other) const;
+ bool strictlyEquals(const QScriptValue& other) const;
+ bool instanceOf(const QScriptValue& other) const;
+
+ QScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const;
+ QScriptValue property(const QScriptString& name, const ResolveFlags& mode = ResolvePrototype) const;
+ QScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const;
+
+ void setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags);
+ void setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags);
+ void setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags);
+
+ PropertyFlags propertyFlags(const QString& name, const ResolveFlags& mode = ResolvePrototype) const;
+ PropertyFlags propertyFlags(const QScriptString& name, const ResolveFlags& mode = ResolvePrototype) 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;
+ bool isArray() const;
+ bool isDate() 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 toObject() const;
+ QDateTime toDateTime() 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/Source/JavaScriptCore/qt/api/qscriptvalue_p.h b/Source/JavaScriptCore/qt/api/qscriptvalue_p.h
new file mode 100644
index 0000000..f98a06a
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -0,0 +1,1220 @@
+/*
+ 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 <JavaScriptCore/JSRetainPtr.h>
+#include <JSObjectRefPrivate.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qnumeric.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::State. Each method should check for the current state and then perform a
+ correct action.
+
+ State:
+ 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_bool
+ CNull -> QSVP is null, but a JSC engine hasn't been associated yet.
+ CUndefined -> QSVP is undefined, but a JSC engine hasn't been associated yet.
+ 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.
+ JSPrimitive -> 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.
+
+ The QScriptValuePrivate use the JSC C API directly. The QSVP type is equal to combination of
+ the JSValueRef and the JSObjectRef, and it could be automatically casted to these types by cast
+ operators.
+*/
+
+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 QScriptEnginePrivate* engine, bool value);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, int value);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value);
+
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value);
+ inline QScriptValuePrivate(const QScriptEnginePrivate* engine, 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 bool isArray();
+ inline bool isDate();
+
+ 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 QScriptValuePrivate* toObject(QScriptEnginePrivate* engine);
+ inline QScriptValuePrivate* toObject();
+ inline QDateTime toDateTime();
+ inline QScriptValuePrivate* prototype();
+ inline void setPrototype(QScriptValuePrivate* prototype);
+
+ inline bool equals(QScriptValuePrivate* other);
+ inline bool strictlyEquals(QScriptValuePrivate* other);
+ inline bool instanceOf(QScriptValuePrivate* other);
+ inline bool assignEngine(QScriptEnginePrivate* engine);
+
+ inline QScriptValuePrivate* property(const QString& name, const QScriptValue::ResolveFlags& mode);
+ inline QScriptValuePrivate* property(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode);
+ inline QScriptValuePrivate* property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode);
+ inline JSValueRef property(quint32 property, JSValueRef* exception);
+ inline JSValueRef property(JSStringRef property, JSValueRef* exception);
+ inline bool hasOwnProperty(quint32 property);
+ inline bool hasOwnProperty(JSStringRef property);
+ template<typename T>
+ inline QScriptValuePrivate* property(T name, const QScriptValue::ResolveFlags& mode);
+
+ inline void setProperty(const QString& name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags);
+ inline void setProperty(const QScriptStringPrivate* name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags);
+ inline void setProperty(const quint32 indexArray, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags);
+ inline void setProperty(quint32 property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception);
+ inline void setProperty(JSStringRef property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception);
+ inline void deleteProperty(quint32 property, JSValueRef* exception);
+ inline void deleteProperty(JSStringRef property, JSValueRef* exception);
+ template<typename T>
+ inline void setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags);
+
+ QScriptValue::PropertyFlags propertyFlags(const QString& name, const QScriptValue::ResolveFlags& mode);
+ QScriptValue::PropertyFlags propertyFlags(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode);
+ QScriptValue::PropertyFlags propertyFlags(const JSStringRef name, const QScriptValue::ResolveFlags& mode);
+
+ inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args);
+
+ inline operator JSValueRef() const;
+ inline operator JSObjectRef() const;
+
+ inline QScriptEnginePrivate* engine() const;
+
+private:
+ // Please, update class documentation when you change the enum.
+ enum State {
+ Invalid = 0,
+ CString = 0x1000,
+ CNumber,
+ CBool,
+ CNull,
+ CUndefined,
+ JSValue = 0x2000, // JS values are equal or higher then this value.
+ JSPrimitive,
+ JSObject
+ } m_state;
+ QScriptEnginePtr m_engine;
+ union Value
+ {
+ bool m_bool;
+ qsreal m_number;
+ JSValueRef m_value;
+ JSObjectRef m_object;
+ QString* m_string;
+
+ Value() : m_number(0) {}
+ Value(bool value) : m_bool(value) {}
+ Value(int number) : m_number(number) {}
+ Value(uint number) : m_number(number) {}
+ Value(qsreal number) : m_number(number) {}
+ Value(JSValueRef value) : m_value(value) {}
+ Value(JSObjectRef object) : m_object(object) {}
+ Value(QString* string) : m_string(string) {}
+ } u;
+
+ inline State refinedJSValue();
+
+ 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 (isJSBased())
+ JSValueUnprotect(*m_engine, u.m_value);
+ else if (isStringBased())
+ delete u.m_string;
+}
+
+QScriptValuePrivate::QScriptValuePrivate()
+ : m_state(Invalid)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QString& string)
+ : m_state(CString)
+ , u(new QString(string))
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(bool value)
+ : m_state(CBool)
+ , u(value)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(int number)
+ : m_state(CNumber)
+ , u(number)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(uint number)
+ : m_state(CNumber)
+ , u(number)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(qsreal number)
+ : m_state(CNumber)
+ , u(number)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value)
+ : m_state(value == QScriptValue::NullValue ? CNull : CUndefined)
+{
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, bool value)
+ : m_state(JSPrimitive)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(engine->makeJSValue(value))
+{
+ Q_ASSERT(engine);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, int value)
+ : m_state(JSPrimitive)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(m_engine->makeJSValue(value))
+{
+ Q_ASSERT(engine);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value)
+ : m_state(JSPrimitive)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(m_engine->makeJSValue(value))
+{
+ Q_ASSERT(engine);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value)
+ : m_state(JSPrimitive)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(m_engine->makeJSValue(value))
+{
+ Q_ASSERT(engine);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value)
+ : m_state(JSPrimitive)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(m_engine->makeJSValue(value))
+{
+ Q_ASSERT(engine);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value)
+ : m_state(JSPrimitive)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(m_engine->makeJSValue(value))
+{
+ Q_ASSERT(engine);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value)
+ : m_state(JSValue)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(value)
+{
+ Q_ASSERT(engine);
+ Q_ASSERT(value);
+ JSValueProtect(*m_engine, u.m_value);
+}
+
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSObjectRef object)
+ : m_state(JSObject)
+ , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+ , u(object)
+{
+ Q_ASSERT(engine);
+ Q_ASSERT(object);
+ JSValueProtect(*m_engine, object);
+}
+
+bool QScriptValuePrivate::isValid() const { return m_state != Invalid; }
+
+bool QScriptValuePrivate::isBool()
+{
+ switch (m_state) {
+ case CBool:
+ return true;
+ case JSValue:
+ if (refinedJSValue() != JSPrimitive)
+ return false;
+ // Fall-through.
+ case JSPrimitive:
+ return JSValueIsBoolean(*m_engine, *this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isNumber()
+{
+ switch (m_state) {
+ case CNumber:
+ return true;
+ case JSValue:
+ if (refinedJSValue() != JSPrimitive)
+ return false;
+ // Fall-through.
+ case JSPrimitive:
+ return JSValueIsNumber(*m_engine, *this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isNull()
+{
+ switch (m_state) {
+ case CNull:
+ return true;
+ case JSValue:
+ if (refinedJSValue() != JSPrimitive)
+ return false;
+ // Fall-through.
+ case JSPrimitive:
+ return JSValueIsNull(*m_engine, *this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isString()
+{
+ switch (m_state) {
+ case CString:
+ return true;
+ case JSValue:
+ if (refinedJSValue() != JSPrimitive)
+ return false;
+ // Fall-through.
+ case JSPrimitive:
+ return JSValueIsString(*m_engine, *this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isUndefined()
+{
+ switch (m_state) {
+ case CUndefined:
+ return true;
+ case JSValue:
+ if (refinedJSValue() != JSPrimitive)
+ return false;
+ // Fall-through.
+ case JSPrimitive:
+ return JSValueIsUndefined(*m_engine, *this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isError()
+{
+ switch (m_state) {
+ case JSValue:
+ if (refinedJSValue() != JSObject)
+ return false;
+ // Fall-through.
+ case JSObject:
+ return m_engine->isError(*this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isObject()
+{
+ switch (m_state) {
+ case JSValue:
+ return refinedJSValue() == JSObject;
+ case JSObject:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isFunction()
+{
+ switch (m_state) {
+ case JSValue:
+ if (refinedJSValue() != JSObject)
+ return false;
+ // Fall-through.
+ case JSObject:
+ return JSObjectIsFunction(*m_engine, *this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isArray()
+{
+ switch (m_state) {
+ case JSValue:
+ if (refinedJSValue() != JSObject)
+ return false;
+ // Fall-through.
+ case JSObject:
+ return m_engine->isArray(*this);
+ default:
+ return false;
+ }
+}
+
+bool QScriptValuePrivate::isDate()
+{
+ switch (m_state) {
+ case JSValue:
+ if (refinedJSValue() != JSObject)
+ return false;
+ // Fall-through.
+ case JSObject:
+ return m_engine->isDate(*this);
+ default:
+ return false;
+ }
+}
+
+QString QScriptValuePrivate::toString() const
+{
+ switch (m_state) {
+ case Invalid:
+ return QString();
+ case CBool:
+ return u.m_bool ? QString::fromLatin1("true") : QString::fromLatin1("false");
+ case CString:
+ return *u.m_string;
+ case CNumber:
+ return QScriptConverter::toString(u.m_number);
+ case CNull:
+ return QString::fromLatin1("null");
+ case CUndefined:
+ return QString::fromLatin1("undefined");
+ case JSValue:
+ case JSPrimitive:
+ case JSObject:
+ JSValueRef exception = 0;
+ JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(*m_engine, *this, &exception));
+ m_engine->setException(exception);
+ return QScriptConverter::toString(ptr.get());
+ }
+
+ Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement.");
+ return QString(); // Avoid compiler warning.
+}
+
+qsreal QScriptValuePrivate::toNumber() const
+{
+ switch (m_state) {
+ case JSValue:
+ case JSPrimitive:
+ case JSObject:
+ {
+ JSValueRef exception = 0;
+ qsreal result = JSValueToNumber(*m_engine, *this, &exception);
+ m_engine->setException(exception);
+ return result;
+ }
+ case CNumber:
+ return u.m_number;
+ case CBool:
+ return u.m_bool ? 1 : 0;
+ case CNull:
+ case Invalid:
+ return 0;
+ case CUndefined:
+ return qQNaN();
+ case CString:
+ bool ok;
+ qsreal result = u.m_string->toDouble(&ok);
+ if (ok)
+ return result;
+ result = u.m_string->toInt(&ok, 0); // Try other bases.
+ if (ok)
+ return result;
+ if (*u.m_string == "Infinity" || *u.m_string == "-Infinity")
+ return qInf();
+ return u.m_string->length() ? qQNaN() : 0;
+ }
+
+ 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 JSPrimitive:
+ return JSValueToBoolean(*m_engine, *this);
+ case JSObject:
+ return true;
+ case CNumber:
+ return !(qIsNaN(u.m_number) || !u.m_number);
+ case CBool:
+ return u.m_bool;
+ case Invalid:
+ case CNull:
+ case CUndefined:
+ return false;
+ case CString:
+ return u.m_string->length();
+ }
+
+ Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
+ return false; // Avoid compiler warning.
+}
+
+qsreal QScriptValuePrivate::toInteger() const
+{
+ qsreal result = toNumber();
+ if (qIsNaN(result))
+ return 0;
+ if (qIsInf(result))
+ return result;
+ return (result > 0) ? qFloor(result) : -1 * qFloor(-result);
+}
+
+qint32 QScriptValuePrivate::toInt32() const
+{
+ qsreal result = toInteger();
+ // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
+ // some of these operation are invoked in toInteger subcall.
+ if (qIsInf(result))
+ return 0;
+ return result;
+}
+
+quint32 QScriptValuePrivate::toUInt32() const
+{
+ qsreal result = toInteger();
+ // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
+ // some of these operation are invoked in toInteger subcall.
+ if (qIsInf(result))
+ return 0;
+ return result;
+}
+
+quint16 QScriptValuePrivate::toUInt16() const
+{
+ return toInt32();
+}
+
+/*!
+ Creates a copy of this value and converts it to an object. If this value is an object
+ then pointer to this value will be returned.
+ \attention it should not happen but if this value is bounded to a different engine that the given, the first
+ one will be used.
+ \internal
+ */
+QScriptValuePrivate* QScriptValuePrivate::toObject(QScriptEnginePrivate* engine)
+{
+ switch (m_state) {
+ case Invalid:
+ case CNull:
+ case CUndefined:
+ return new QScriptValuePrivate;
+ case CString:
+ {
+ // Exception can't occur here.
+ JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(*u.m_string), /* exception */ 0);
+ Q_ASSERT(object);
+ return new QScriptValuePrivate(engine, object);
+ }
+ case CNumber:
+ {
+ // Exception can't occur here.
+ JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(u.m_number), /* exception */ 0);
+ Q_ASSERT(object);
+ return new QScriptValuePrivate(engine, object);
+ }
+ case CBool:
+ {
+ // Exception can't occure here.
+ JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(u.m_bool), /* exception */ 0);
+ Q_ASSERT(object);
+ return new QScriptValuePrivate(engine, object);
+ }
+ case JSValue:
+ if (refinedJSValue() != JSPrimitive)
+ break;
+ // Fall-through.
+ case JSPrimitive:
+ {
+ if (engine != this->engine())
+ qWarning("QScriptEngine::toObject: cannot convert value created in a different engine");
+ JSValueRef exception = 0;
+ JSObjectRef object = JSValueToObject(*m_engine, *this, &exception);
+ if (object)
+ return new QScriptValuePrivate(m_engine.constData(), object);
+ else
+ m_engine->setException(exception, QScriptEnginePrivate::NotNullException);
+
+ }
+ return new QScriptValuePrivate;
+ case JSObject:
+ break;
+ }
+
+ if (engine != this->engine())
+ qWarning("QScriptEngine::toObject: cannot convert value created in a different engine");
+ Q_ASSERT(m_state == JSObject);
+ return this;
+}
+
+/*!
+ This method is created only for QScriptValue::toObject() purpose which is obsolete.
+ \internal
+ */
+QScriptValuePrivate* QScriptValuePrivate::toObject()
+{
+ if (isJSBased())
+ return toObject(m_engine.data());
+
+ // Without an engine there is not much we can do.
+ return new QScriptValuePrivate;
+}
+
+QDateTime QScriptValuePrivate::toDateTime()
+{
+ if (!isDate())
+ return QDateTime();
+
+ JSValueRef exception = 0;
+ qsreal t = JSValueToNumber(*m_engine, *this, &exception);
+
+ if (exception) {
+ m_engine->setException(exception, QScriptEnginePrivate::NotNullException);
+ return QDateTime();
+ }
+
+ QDateTime result;
+ result.setMSecsSinceEpoch(qint64(t));
+ return result;
+}
+
+inline QScriptValuePrivate* QScriptValuePrivate::prototype()
+{
+ if (isObject()) {
+ JSValueRef prototype = JSObjectGetPrototype(*m_engine, *this);
+ if (JSValueIsNull(*m_engine, prototype))
+ return new QScriptValuePrivate(engine(), prototype);
+ // The prototype could be either a null or a JSObject, so it is safe to cast the prototype
+ // to the JSObjectRef here.
+ return new QScriptValuePrivate(engine(), const_cast<JSObjectRef>(prototype));
+ }
+ return new QScriptValuePrivate;
+}
+
+inline void QScriptValuePrivate::setPrototype(QScriptValuePrivate* prototype)
+{
+ if (isObject() && prototype->isValid() && (prototype->isObject() || prototype->isNull())) {
+ if (engine() != prototype->engine()) {
+ qWarning("QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
+ return;
+ }
+ // FIXME: This could be replaced by a new, faster API
+ // look at https://bugs.webkit.org/show_bug.cgi?id=40060
+ JSObjectSetPrototype(*m_engine, *this, *prototype);
+ JSValueRef proto = JSObjectGetPrototype(*m_engine, *this);
+ if (!JSValueIsStrictEqual(*m_engine, proto, *prototype))
+ qWarning("QScriptValue::setPrototype() failed: cyclic prototype value");
+ }
+}
+
+bool QScriptValuePrivate::equals(QScriptValuePrivate* other)
+{
+ if (!isValid())
+ return !other->isValid();
+
+ if (!other->isValid())
+ return false;
+
+ if (!isJSBased() && !other->isJSBased()) {
+ switch (m_state) {
+ case CNull:
+ case CUndefined:
+ return other->isUndefined() || other->isNull();
+ case CNumber:
+ switch (other->m_state) {
+ case CBool:
+ case CString:
+ return u.m_number == other->toNumber();
+ case CNumber:
+ return u.m_number == other->u.m_number;
+ default:
+ return false;
+ }
+ case CBool:
+ switch (other->m_state) {
+ case CBool:
+ return u.m_bool == other->u.m_bool;
+ case CNumber:
+ return toNumber() == other->u.m_number;
+ case CString:
+ return toNumber() == other->toNumber();
+ default:
+ return false;
+ }
+ case CString:
+ switch (other->m_state) {
+ case CBool:
+ return toNumber() == other->toNumber();
+ case CNumber:
+ return toNumber() == other->u.m_number;
+ case CString:
+ return *u.m_string == *other->u.m_string;
+ default:
+ return false;
+ }
+ default:
+ Q_ASSERT_X(false, "equals()", "Not all states are included in the previous switch statement.");
+ }
+ }
+
+ 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 (!assignEngine(other->engine())) {
+ qWarning("equals(): Cannot compare to a value created in a different engine");
+ return false;
+ }
+ }
+
+ JSValueRef exception = 0;
+ bool result = JSValueIsEqual(*m_engine, *this, *other, &exception);
+ m_engine->setException(exception);
+ return result;
+}
+
+bool QScriptValuePrivate::strictlyEquals(QScriptValuePrivate* other)
+{
+ if (isJSBased()) {
+ // We can't compare these two values without binding to the same engine.
+ if (!other->isJSBased()) {
+ if (other->assignEngine(engine()))
+ return JSValueIsStrictEqual(*m_engine, *this, *other);
+ return false;
+ }
+ if (other->engine() != engine()) {
+ qWarning("strictlyEquals(): Cannot compare to a value created in a different engine");
+ return false;
+ }
+ return JSValueIsStrictEqual(*m_engine, *this, *other);
+ }
+ if (isStringBased()) {
+ if (other->isStringBased())
+ return *u.m_string == *(other->u.m_string);
+ if (other->isJSBased()) {
+ assignEngine(other->engine());
+ return JSValueIsStrictEqual(*m_engine, *this, *other);
+ }
+ }
+ if (isNumberBased()) {
+ if (other->isNumberBased())
+ return u.m_number == other->u.m_number;
+ if (other->isJSBased()) {
+ assignEngine(other->engine());
+ return JSValueIsStrictEqual(*m_engine, *this, *other);
+ }
+ }
+ if (!isValid() && !other->isValid())
+ return true;
+
+ return false;
+}
+
+inline bool QScriptValuePrivate::instanceOf(QScriptValuePrivate* other)
+{
+ if (!isJSBased() || !other->isObject())
+ return false;
+ JSValueRef exception = 0;
+ bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, *other, &exception);
+ m_engine->setException(exception);
+ return result;
+}
+
+/*!
+ Tries to assign \a engine to this value. Returns true on success; otherwise returns false.
+*/
+bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
+{
+ Q_ASSERT(engine);
+ JSValueRef value;
+ switch (m_state) {
+ case CBool:
+ value = engine->makeJSValue(u.m_bool);
+ break;
+ case CString:
+ value = engine->makeJSValue(*u.m_string);
+ delete u.m_string;
+ break;
+ case CNumber:
+ value = engine->makeJSValue(u.m_number);
+ break;
+ case CNull:
+ value = engine->makeJSValue(QScriptValue::NullValue);
+ break;
+ case CUndefined:
+ value = engine->makeJSValue(QScriptValue::UndefinedValue);
+ 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 = JSPrimitive;
+ u.m_value = value;
+ JSValueProtect(*m_engine, value);
+ return true;
+}
+
+inline QScriptValuePrivate* QScriptValuePrivate::property(const QString& name, const QScriptValue::ResolveFlags& mode)
+{
+ JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name));
+ return property<JSStringRef>(propertyName.get(), mode);
+}
+
+inline QScriptValuePrivate* QScriptValuePrivate::property(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode)
+{
+ return property<JSStringRef>(*name, mode);
+}
+
+inline QScriptValuePrivate* QScriptValuePrivate::property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode)
+{
+ return property<quint32>(arrayIndex, mode);
+}
+
+/*!
+ \internal
+ This method was created to unify access to the JSObjectGetPropertyAtIndex and the JSObjectGetProperty.
+*/
+inline JSValueRef QScriptValuePrivate::property(quint32 property, JSValueRef* exception)
+{
+ return JSObjectGetPropertyAtIndex(*m_engine, *this, property, exception);
+}
+
+/*!
+ \internal
+ This method was created to unify access to the JSObjectGetPropertyAtIndex and the JSObjectGetProperty.
+*/
+inline JSValueRef QScriptValuePrivate::property(JSStringRef property, JSValueRef* exception)
+{
+ return JSObjectGetProperty(*m_engine, *this, property, exception);
+}
+
+/*!
+ \internal
+ This method was created to unify acccess to hasOwnProperty, same function for an array index
+ and a property name access.
+*/
+inline bool QScriptValuePrivate::hasOwnProperty(quint32 property)
+{
+ Q_ASSERT(isObject());
+ // FIXME it could be faster, but JSC C API doesn't expose needed functionality.
+ JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property)));
+ return hasOwnProperty(propertyName.get());
+}
+
+/*!
+ \internal
+ This method was created to unify acccess to hasOwnProperty, same function for an array index
+ and a property name access.
+*/
+inline bool QScriptValuePrivate::hasOwnProperty(JSStringRef property)
+{
+ Q_ASSERT(isObject());
+ return m_engine->objectHasOwnProperty(*this, property);
+}
+
+/*!
+ \internal
+ This function gets property of an object.
+ \arg propertyName could be type of quint32 (an array index) or JSStringRef (a property name).
+*/
+template<typename T>
+inline QScriptValuePrivate* QScriptValuePrivate::property(T propertyName, const QScriptValue::ResolveFlags& mode)
+{
+ if (!isObject())
+ return new QScriptValuePrivate();
+
+ if ((mode == QScriptValue::ResolveLocal) && (!hasOwnProperty(propertyName)))
+ return new QScriptValuePrivate();
+
+ JSValueRef exception = 0;
+ JSValueRef value = property(propertyName, &exception);
+
+ if (exception) {
+ m_engine->setException(exception, QScriptEnginePrivate::NotNullException);
+ return new QScriptValuePrivate(engine(), exception);
+ }
+ if (JSValueIsUndefined(*m_engine, value))
+ return new QScriptValuePrivate;
+ return new QScriptValuePrivate(engine(), value);
+}
+
+inline void QScriptValuePrivate::setProperty(const QString& name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags)
+{
+ JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name));
+ setProperty<JSStringRef>(propertyName.get(), value, flags);
+}
+
+inline void QScriptValuePrivate::setProperty(quint32 arrayIndex, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags)
+{
+ setProperty<quint32>(arrayIndex, value, flags);
+}
+
+inline void QScriptValuePrivate::setProperty(const QScriptStringPrivate* name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags)
+{
+ setProperty<JSStringRef>(*name, value, flags);
+}
+
+/*!
+ \internal
+ This method was created to unify access to the JSObjectSetPropertyAtIndex and the JSObjectSetProperty.
+*/
+inline void QScriptValuePrivate::setProperty(quint32 property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception)
+{
+ Q_ASSERT(isObject());
+ if (flags) {
+ // FIXME This could be better, but JSC C API doesn't expose needed functionality. It is
+ // not possible to create / modify a property attribute via an array index.
+ JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property)));
+ JSObjectSetProperty(*m_engine, *this, propertyName.get(), value, flags, exception);
+ return;
+ }
+ JSObjectSetPropertyAtIndex(*m_engine, *this, property, value, exception);
+}
+
+/*!
+ \internal
+ This method was created to unify access to the JSObjectSetPropertyAtIndex and the JSObjectSetProperty.
+*/
+inline void QScriptValuePrivate::setProperty(JSStringRef property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception)
+{
+ Q_ASSERT(isObject());
+ JSObjectSetProperty(*m_engine, *this, property, value, flags, exception);
+}
+
+/*!
+ \internal
+ This method was created to unify access to the JSObjectDeleteProperty and a teoretical JSObjectDeletePropertyAtIndex
+ which doesn't exist now.
+*/
+inline void QScriptValuePrivate::deleteProperty(quint32 property, JSValueRef* exception)
+{
+ // FIXME It could be faster, we need a JSC C API for deleting array index properties.
+ JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property)));
+ JSObjectDeleteProperty(*m_engine, *this, propertyName.get(), exception);
+}
+
+/*!
+ \internal
+ This method was created to unify access to the JSObjectDeleteProperty and a teoretical JSObjectDeletePropertyAtIndex.
+*/
+inline void QScriptValuePrivate::deleteProperty(JSStringRef property, JSValueRef* exception)
+{
+ Q_ASSERT(isObject());
+ JSObjectDeleteProperty(*m_engine, *this, property, exception);
+}
+
+template<typename T>
+inline void QScriptValuePrivate::setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags)
+{
+ if (!isObject())
+ return;
+
+ if (!value->isJSBased())
+ value->assignEngine(engine());
+
+ JSValueRef exception = 0;
+ if (!value->isValid()) {
+ // Remove the property.
+ deleteProperty(name, &exception);
+ m_engine->setException(exception);
+ return;
+ }
+ if (m_engine != value->m_engine) {
+ qWarning("QScriptValue::setProperty() failed: cannot set value created in a different engine");
+ return;
+ }
+
+ setProperty(name, *value, QScriptConverter::toPropertyFlags(flags), &exception);
+ m_engine->setException(exception);
+}
+
+inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const QString& name, const QScriptValue::ResolveFlags& mode)
+{
+ JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name));
+ return propertyFlags(propertyName.get(), mode);
+}
+
+inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode)
+{
+ return propertyFlags(*name, mode);
+}
+
+inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(JSStringRef name, const QScriptValue::ResolveFlags& mode)
+{
+ unsigned flags = 0;
+ if (!isObject())
+ return QScriptValue::PropertyFlags(flags);
+
+ // FIXME It could be faster and nicer, but new JSC C API should be created.
+ static JSStringRef objectName = QScriptConverter::toString("Object");
+ static JSStringRef propertyDescriptorName = QScriptConverter::toString("getOwnPropertyDescriptor");
+
+ // FIXME This is dangerous if global object was modified (bug 41839).
+ JSValueRef exception = 0;
+ JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine);
+ JSValueRef objectConstructor = JSObjectGetProperty(*m_engine, globalObject, objectName, &exception);
+ Q_ASSERT(JSValueIsObject(*m_engine, objectConstructor));
+ JSValueRef propertyDescriptorGetter = JSObjectGetProperty(*m_engine, const_cast<JSObjectRef>(objectConstructor), propertyDescriptorName, &exception);
+ Q_ASSERT(JSValueIsObject(*m_engine, propertyDescriptorGetter));
+
+ JSValueRef arguments[] = { *this, JSValueMakeString(*m_engine, name) };
+ JSObjectRef propertyDescriptor
+ = const_cast<JSObjectRef>(JSObjectCallAsFunction(*m_engine,
+ const_cast<JSObjectRef>(propertyDescriptorGetter),
+ /* thisObject */ 0,
+ /* argumentCount */ 2,
+ arguments,
+ &exception));
+ if (exception) {
+ // Invalid property.
+ return QScriptValue::PropertyFlags(flags);
+ }
+
+ if (!JSValueIsObject(*m_engine, propertyDescriptor)) {
+ // Property isn't owned by this object.
+ JSObjectRef proto;
+ if (mode == QScriptValue::ResolveLocal
+ || ((proto = const_cast<JSObjectRef>(JSObjectGetPrototype(*m_engine, *this))) && JSValueIsNull(*m_engine, proto))) {
+ return QScriptValue::PropertyFlags(flags);
+ }
+ QScriptValuePrivate p(engine(), proto);
+ return p.propertyFlags(name, QScriptValue::ResolvePrototype);
+ }
+
+ static JSStringRef writableName = QScriptConverter::toString("writable");
+ static JSStringRef configurableName = QScriptConverter::toString("configurable");
+ static JSStringRef enumerableName = QScriptConverter::toString("enumerable");
+
+ bool readOnly = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, writableName, &exception));
+ if (!exception && readOnly)
+ flags |= QScriptValue::ReadOnly;
+ bool undeletable = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, configurableName, &exception));
+ if (!exception && undeletable)
+ flags |= QScriptValue::Undeletable;
+ bool skipInEnum = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, enumerableName, &exception));
+ if (!exception && skipInEnum)
+ flags |= QScriptValue::SkipInEnumeration;
+
+ return QScriptValue::PropertyFlags(flags);
+}
+
+QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args)
+{
+ switch (m_state) {
+ case JSValue:
+ if (refinedJSValue() != JSObject)
+ return new QScriptValuePrivate;
+ // 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;
+ }
+
+ // Make the call
+ JSValueRef exception = 0;
+ JSValueRef result = JSObjectCallAsFunction(*m_engine, *this, /* thisObject */ 0, argc, argv.constData(), &exception);
+ if (!result && exception) {
+ m_engine->setException(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();
+}
+
+QScriptValuePrivate::operator JSValueRef() const
+{
+ Q_ASSERT(isJSBased());
+ Q_ASSERT(u.m_value);
+ return u.m_value;
+}
+
+QScriptValuePrivate::operator JSObjectRef() const
+{
+ Q_ASSERT(m_state == JSObject);
+ Q_ASSERT(u.m_object);
+ return u.m_object;
+}
+
+/*!
+ \internal
+ Refines the state of this QScriptValuePrivate. Returns the new state.
+*/
+QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue()
+{
+ Q_ASSERT(m_state == JSValue);
+ if (!JSValueIsObject(*m_engine, *this)) {
+ m_state = JSPrimitive;
+ } else {
+ // Difference between JSValueRef and JSObjectRef is only in their type, binarywise it is the same.
+ // As m_value and m_object are stored in the u union, it is enough to change the m_state only.
+ m_state = JSObject;
+ }
+ return m_state;
+}
+
+/*!
+ \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 m_state == CNumber || m_state == CBool; }
+
+/*!
+ \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/Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp
new file mode 100644
index 0000000..f1caa61
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp
@@ -0,0 +1,226 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#include "qscriptvalueiterator.h"
+
+#include "qscriptvalue_p.h"
+#include "qscriptvalueiterator_p.h"
+
+/*!
+ \class QScriptValueIterator
+
+ \brief The QScriptValueIterator class provides a Java-style iterator for QScriptValue.
+
+ \ingroup script
+
+
+ The QScriptValueIterator constructor takes a QScriptValue as
+ argument. After construction, the iterator is located at the very
+ beginning of the sequence of properties. Here's how to iterate over
+ all the properties of a QScriptValue:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 0
+
+ The next() advances the iterator. The name(), value() and flags()
+ functions return the name, value and flags of the last item that was
+ jumped over.
+
+ If you want to remove properties as you iterate over the
+ QScriptValue, use remove(). If you want to modify the value of a
+ property, use setValue().
+
+ Note that QScriptValueIterator only iterates over the QScriptValue's
+ own properties; i.e. it does not follow the prototype chain. You can
+ use a loop like this to follow the prototype chain:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 1
+
+ Note that QScriptValueIterator will not automatically skip over
+ properties that have the QScriptValue::SkipInEnumeration flag set;
+ that flag only affects iteration in script code. If you want, you
+ can skip over such properties with code like the following:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 2
+
+ \sa QScriptValue::property()
+*/
+
+/*!
+ Constructs an iterator for traversing \a object. The iterator is
+ set to be at the front of the sequence of properties (before the
+ first property).
+*/
+QScriptValueIterator::QScriptValueIterator(const QScriptValue& object)
+ : d_ptr(new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object)))
+{}
+
+/*!
+ Destroys the iterator.
+*/
+QScriptValueIterator::~QScriptValueIterator()
+{}
+
+/*!
+ Returns true if there is at least one item ahead of the iterator
+ (i.e. the iterator is \e not at the back of the property sequence);
+ otherwise returns false.
+
+ \sa next(), hasPrevious()
+*/
+bool QScriptValueIterator::hasNext() const
+{
+ return d_ptr->hasNext();
+}
+
+/*!
+ Advances the iterator by one position.
+
+ Calling this function on an iterator located at the back of the
+ container leads to undefined results.
+
+ \sa hasNext(), previous(), name()
+*/
+void QScriptValueIterator::next()
+{
+ d_ptr->next();
+}
+
+/*!
+ Returns true if there is at least one item behind the iterator
+ (i.e. the iterator is \e not at the front of the property sequence);
+ otherwise returns false.
+
+ \sa previous(), hasNext()
+*/
+bool QScriptValueIterator::hasPrevious() const
+{
+ return d_ptr->hasPrevious();
+}
+
+/*!
+ Moves the iterator back by one position.
+
+ Calling this function on an iterator located at the front of the
+ container leads to undefined results.
+
+ \sa hasPrevious(), next(), name()
+*/
+void QScriptValueIterator::previous()
+{
+ d_ptr->previous();
+}
+
+/*!
+ Moves the iterator to the front of the QScriptValue (before the
+ first property).
+
+ \sa toBack(), next()
+*/
+void QScriptValueIterator::toFront()
+{
+ d_ptr->toFront();
+}
+
+/*!
+ Moves the iterator to the back of the QScriptValue (after the
+ last property).
+
+ \sa toFront(), previous()
+*/
+void QScriptValueIterator::toBack()
+{
+ d_ptr->toBack();
+}
+
+/*!
+ Returns the name of the last property that was jumped over using
+ next() or previous().
+
+ \sa value(), flags()
+*/
+QString QScriptValueIterator::name() const
+{
+ return d_ptr->name();
+}
+
+/*!
+ Returns the name of the last property that was jumped over using
+ next() or previous().
+*/
+QScriptString QScriptValueIterator::scriptName() const
+{
+ return QScriptStringPrivate::get(d_ptr->scriptName());
+}
+
+/*!
+ Returns the value of the last property that was jumped over using
+ next() or previous().
+
+ \sa setValue(), name()
+*/
+QScriptValue QScriptValueIterator::value() const
+{
+ return QScriptValuePrivate::get(d_ptr->value());
+}
+
+/*!
+ Sets the \a value of the last property that was jumped over using
+ next() or previous().
+
+ \sa value(), name()
+*/
+void QScriptValueIterator::setValue(const QScriptValue& value)
+{
+ d_ptr->setValue(QScriptValuePrivate::get(value));
+}
+
+/*!
+ Removes the last property that was jumped over using next()
+ or previous().
+
+ \sa setValue()
+*/
+void QScriptValueIterator::remove()
+{
+ d_ptr->remove();
+}
+
+/*!
+ Returns the flags of the last property that was jumped over using
+ next() or previous().
+
+ \sa value()
+*/
+QScriptValue::PropertyFlags QScriptValueIterator::flags() const
+{
+ return d_ptr->flags();
+}
+
+/*!
+ Makes the iterator operate on \a object. The iterator is set to be
+ at the front of the sequence of properties (before the first
+ property).
+*/
+QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue& object)
+{
+ d_ptr = new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object));
+ return *this;
+}
diff --git a/Source/JavaScriptCore/qt/api/qscriptvalueiterator.h b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.h
new file mode 100644
index 0000000..0c90661
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.h
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptvalueiterator_h
+#define qscriptvalueiterator_h
+
+#include "qtscriptglobal.h"
+#include "qscriptstring.h"
+#include <QtCore/qshareddata.h>
+#include "qscriptvalue.h"
+
+class QScriptValue;
+class QScriptValueIteratorPrivate;
+
+
+class Q_JAVASCRIPT_EXPORT QScriptValueIterator {
+public:
+ QScriptValueIterator(const QScriptValue& value);
+ ~QScriptValueIterator();
+
+ bool hasNext() const;
+ void next();
+
+ bool hasPrevious() const;
+ void previous();
+
+ QString name() const;
+ QScriptString scriptName() const;
+
+ QScriptValue value() const;
+ void setValue(const QScriptValue& value);
+
+ void remove();
+ QScriptValue::PropertyFlags flags() const;
+
+ void toFront();
+ void toBack();
+
+ QScriptValueIterator& operator=(QScriptValue& value);
+private:
+ QExplicitlySharedDataPointer<QScriptValueIteratorPrivate> d_ptr;
+
+ Q_DECLARE_PRIVATE(QScriptValueIterator)
+ Q_DISABLE_COPY(QScriptValueIterator)
+};
+
+#endif // qscriptvalueiterator_h
diff --git a/Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h b/Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
new file mode 100644
index 0000000..b93b518
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
@@ -0,0 +1,172 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptvalueiterator_p_h
+#define qscriptvalueiterator_p_h
+
+#include "qscriptvalue_p.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qvector.h>
+
+class QScriptValueIteratorPrivate: public QSharedData {
+public:
+ inline QScriptValueIteratorPrivate(const QScriptValuePrivate* value);
+ inline ~QScriptValueIteratorPrivate();
+
+ inline bool hasNext();
+ inline void next();
+
+ inline bool hasPrevious();
+ inline void previous();
+
+ inline QString name() const;
+ inline QScriptStringPrivate* scriptName() const;
+
+ inline QScriptValuePrivate* value() const;
+ inline void setValue(const QScriptValuePrivate* value);
+
+ inline void remove();
+
+ inline void toFront();
+ inline void toBack();
+
+ QScriptValue::PropertyFlags flags() const;
+
+ inline bool isValid() const;
+private:
+ inline QScriptEnginePrivate* engine() const;
+
+ QExplicitlySharedDataPointer<QScriptValuePrivate> m_object;
+ QVector<JSStringRef> m_names;
+ QMutableVectorIterator<JSStringRef> m_idx;
+};
+
+inline QScriptValueIteratorPrivate::QScriptValueIteratorPrivate(const QScriptValuePrivate* value)
+ : m_object(const_cast<QScriptValuePrivate*>(value))
+ , m_idx(m_names)
+{
+ if (m_object->isObject()) {
+ m_names = engine()->objectGetOwnPropertyNames(*m_object);
+ m_idx = m_names;
+ } else
+ m_object = 0;
+}
+
+inline QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate()
+{
+ QVector<JSStringRef>::const_iterator i = m_names.constBegin();
+ for (; i != m_names.constEnd(); ++i)
+ JSStringRelease(*i);
+}
+
+inline bool QScriptValueIteratorPrivate::hasNext()
+{
+ return m_idx.hasNext();
+}
+
+inline void QScriptValueIteratorPrivate::next()
+{
+ // FIXME (Qt5) This method should return a value (QTBUG-11226).
+ m_idx.next();
+}
+
+inline bool QScriptValueIteratorPrivate::hasPrevious()
+{
+ return m_idx.hasPrevious();
+}
+
+inline void QScriptValueIteratorPrivate::previous()
+{
+ m_idx.previous();
+}
+
+inline QString QScriptValueIteratorPrivate::name() const
+{
+ if (!isValid())
+ return QString();
+ return QScriptConverter::toString(m_idx.value());
+}
+
+inline QScriptStringPrivate* QScriptValueIteratorPrivate::scriptName() const
+{
+ if (!isValid())
+ return new QScriptStringPrivate();
+ return new QScriptStringPrivate(QScriptConverter::toString(m_idx.value()));
+}
+
+inline QScriptValuePrivate* QScriptValueIteratorPrivate::value() const
+{
+ if (!isValid())
+ return new QScriptValuePrivate();
+ JSValueRef exception = 0;
+ JSValueRef value = m_object->property(m_idx.value(), &exception);
+ engine()->setException(exception);
+ return new QScriptValuePrivate(engine(), value);
+}
+
+inline void QScriptValueIteratorPrivate::setValue(const QScriptValuePrivate* value)
+{
+ if (!isValid())
+ return;
+ JSValueRef exception = 0;
+ m_object->setProperty(m_idx.value(), *value, /* flags */ 0, &exception);
+ engine()->setException(exception);
+}
+
+inline void QScriptValueIteratorPrivate::remove()
+{
+ if (!isValid())
+ return;
+ JSValueRef exception = 0;
+ m_object->deleteProperty(m_idx.value(), &exception);
+ engine()->setException(exception);
+ m_idx.remove();
+}
+
+inline void QScriptValueIteratorPrivate::toFront()
+{
+ m_idx.toFront();
+}
+
+inline void QScriptValueIteratorPrivate::toBack()
+{
+ m_idx.toBack();
+}
+
+QScriptValue::PropertyFlags QScriptValueIteratorPrivate::flags() const
+{
+ if (!isValid())
+ return QScriptValue::PropertyFlags(0);
+ return m_object->propertyFlags(m_idx.value(), QScriptValue::ResolveLocal);
+}
+
+inline bool QScriptValueIteratorPrivate::isValid() const
+{
+ return m_object;
+}
+
+inline QScriptEnginePrivate* QScriptValueIteratorPrivate::engine() const
+{
+ Q_ASSERT(isValid());
+ return m_object->engine();
+}
+
+#endif // qscriptvalueiterator_p_h
diff --git a/Source/JavaScriptCore/qt/api/qtscriptglobal.h b/Source/JavaScriptCore/qt/api/qtscriptglobal.h
new file mode 100644
index 0000000..efdfc50
--- /dev/null
+++ b/Source/JavaScriptCore/qt/api/qtscriptglobal.h
@@ -0,0 +1,43 @@
+/*
+ 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(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
+
+#if !defined(Q_JAVASCRIPT_EXPORT)
+# if defined(QT_SHARED)
+# define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
+# else
+# define Q_JAVASCRIPT_EXPORT
+# endif
+#endif
+
+#endif