summaryrefslogtreecommitdiff
path: root/src/script/api/qscriptvalue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/api/qscriptvalue.cpp')
-rw-r--r--src/script/api/qscriptvalue.cpp2098
1 files changed, 645 insertions, 1453 deletions
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 91ce9c8..6fd2393 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -21,114 +21,36 @@
**
****************************************************************************/
-#include "config.h"
-#include "qscriptvalue.h"
-
-#include "qscriptvalue_p.h"
+#include "qscriptisolate_p.h"
#include "qscriptengine.h"
#include "qscriptengine_p.h"
-#include "qscriptstring_p.h"
-
-#include "JSGlobalObject.h"
-#include "JSImmediate.h"
-#include "JSObject.h"
-#include "JSValue.h"
-#include "JSFunction.h"
-#include "Identifier.h"
-#include "Operations.h"
-#include "Arguments.h"
+#include "qscriptstring.h"
+#include "qscriptvalue.h"
+#include "qscriptvalue_p.h"
+#include "qscriptclass_p.h"
+#include "qscriptdeclarativeclassobject_p.h"
+#include "qscript_impl_p.h"
+#include "qscriptshareddata_p.h"
+#include <QtCore/qregexp.h>
+#include <QtCore/qstring.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qnumeric.h>
+QT_BEGIN_NAMESPACE
/*!
- \since 4.3
- \class QScriptValue
-
- \brief The QScriptValue class acts as a container for the Qt Script data types.
-
- \ingroup script
- \mainclass
-
- QScriptValue supports the types defined in the \l{ECMA-262}
- standard: The primitive types, which are Undefined, Null, Boolean,
- Number, and String; and the Object type. Additionally, Qt Script
- has built-in support for QVariant, QObject and QMetaObject.
-
- For the object-based types (including Date and RegExp), use the
- newT() functions in QScriptEngine (e.g. QScriptEngine::newObject())
- to create a QScriptValue of the desired type. For the primitive types,
- use one of the QScriptValue constructor overloads.
-
- The methods named isT() (e.g. isBool(), isUndefined()) can be
- used to test if a value is of a certain type. The methods named
- toT() (e.g. toBool(), toString()) can be used to convert a
- QScriptValue to another type. You can also use the generic
- qscriptvalue_cast() function.
-
- Object values have zero or more properties which are themselves
- QScriptValues. Use setProperty() to set a property of an object, and
- call property() to retrieve the value of a property.
-
- \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 0
-
- Each property can have a set of attributes; these are specified as
- the third (optional) argument to setProperty(). The attributes of a
- property can be queried by calling the propertyFlags() function. The
- following code snippet creates a property that cannot be modified by
- script code:
-
- \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 1
-
- If you want to iterate over the properties of a script object, use
- the QScriptValueIterator class.
-
- Object values have an internal \c{prototype} property, which can be
- accessed with prototype() and setPrototype(). Properties added to a
- prototype are shared by all objects having that prototype; this is
- referred to as prototype-based inheritance. In practice, it means
- that (by default) the property() function will automatically attempt
- to look up look the property in the prototype() (and in the
- prototype of the prototype(), and so on), if the object itself does
- not have the requested property. Note that this prototype-based
- lookup is not performed by setProperty(); setProperty() will always
- create the property in the script object itself. For more
- information, see the \l{QtScript} documentation.
-
- Function objects (objects for which isFunction() returns true) can
- be invoked by calling call(). Constructor functions can be used to
- construct new objects by calling construct().
-
- Use equals(), strictlyEquals() and lessThan() to compare a QScriptValue
- to another.
-
- Object values can have custom data associated with them; see the
- setData() and data() functions. By default, this data is not
- accessible to scripts; it can be used to store any data you want to
- associate with the script object. Typically this is used by custom
- class objects (see QScriptClass) to store a C++ type that contains
- the "native" object data.
-
- Note that a QScriptValue for which isObject() is true only carries a
- reference to an actual object; copying the QScriptValue will only
- copy the object reference, not the object itself. If you want to
- clone an object (i.e. copy an object's properties to another
- object), you can do so with the help of a \c{for-in} statement in
- script code, or QScriptValueIterator in C++.
-
- \sa QScriptEngine, QScriptValueIterator
+ Constructs an invalid value.
*/
+QScriptValue::QScriptValue()
+ : d_ptr(InvalidValue())
+{
+}
/*!
- \enum QScriptValue::SpecialValue
-
- This enum is used to specify a single-valued type.
-
- \value UndefinedValue An undefined value.
-
- \value NullValue A null value.
+ Constructs a new QScriptValue with a boolean \a value.
*/
+QScriptValue::QScriptValue(bool value)
+ : d_ptr(new QScriptValuePrivate(value))
+{
+}
/*!
\enum QScriptValue::PropertyFlag
@@ -153,783 +75,376 @@
*/
/*!
- \enum QScriptValue::ResolveFlag
-
- This enum specifies how to look up a property of an object.
-
- \value ResolveLocal Only check the object's own properties.
-
- \value ResolvePrototype Check the object's own properties first, then search the prototype chain. This is the default.
-
- \omitvalue ResolveScope Check the object's own properties first, then search the scope chain.
-
- \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain.
+ Constructs a new QScriptValue with a number \a value.
*/
+QScriptValue::QScriptValue(int value)
+ : d_ptr(new QScriptValuePrivate(value))
+{
+}
-QT_BEGIN_NAMESPACE
+/*!
+ Constructs a new QScriptValue with a number \a value.
+*/
+QScriptValue::QScriptValue(uint value)
+ : d_ptr(new QScriptValuePrivate(value))
+{
+}
-void QScriptValuePrivate::detachFromEngine()
+/*!
+ Constructs a new QScriptValue with a number \a value.
+*/
+QScriptValue::QScriptValue(qsreal value)
+ : d_ptr(new QScriptValuePrivate(value))
{
- if (isJSC())
- jscValue = JSC::JSValue();
- engine = 0;
}
/*!
- \internal
+ Constructs a new QScriptValue with a string \a value.
*/
-QScriptValue::QScriptValue(QScriptValuePrivate *d)
- : d_ptr(d)
+QScriptValue::QScriptValue(const QString& value)
+ : d_ptr(new QScriptValuePrivate(value))
{
}
/*!
- Constructs an invalid QScriptValue.
+ Constructs a new QScriptValue with a special \a value.
*/
-QScriptValue::QScriptValue()
- : d_ptr(0)
+QScriptValue::QScriptValue(SpecialValue value)
+ : d_ptr(new QScriptValuePrivate(value))
{
}
/*!
- Destroys this QScriptValue.
+ Constructs a new QScriptValue with a string \a value.
*/
-QScriptValue::~QScriptValue()
+QScriptValue::QScriptValue(const QLatin1String &value)
+ : d_ptr(new QScriptValuePrivate(value))
{
}
/*!
- Constructs a new QScriptValue that is a copy of \a other.
+ Constructs a new QScriptValue with a string \a value.
+*/
+QScriptValue::QScriptValue(const char* value)
+ : d_ptr(new QScriptValuePrivate(QString::fromUtf8(value)))
+{
+}
- 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).
+/*!
+ Block automatic convertion to bool
+ \internal
*/
-QScriptValue::QScriptValue(const QScriptValue &other)
- : d_ptr(other.d_ptr)
+QScriptValue::QScriptValue(void* d)
{
+ Q_UNUSED(d);
+ Q_ASSERT(false);
}
/*!
- \obsolete
+ Constructs a new QScriptValue from private
+ \internal
+*/
+QScriptValue::QScriptValue(QScriptValuePrivate* d)
+ : d_ptr(d)
+{
+}
- Constructs a new QScriptValue with the special \a value and
- registers it with the script \a engine.
+/*!
+ Constructs a new QScriptValue from private
+ \internal
*/
-QScriptValue::QScriptValue(QScriptEngine *engine, QScriptValue::SpecialValue value)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptPassPointer<QScriptValuePrivate> d)
+ : d_ptr(d.give())
{
- switch (value) {
- case NullValue:
- d_ptr->initFrom(JSC::jsNull());
- break;
- case UndefinedValue:
- d_ptr->initFrom(JSC::jsUndefined());
- break;
- }
}
/*!
\obsolete
- \fn QScriptValue::QScriptValue(QScriptEngine *engine, bool value)
-
Constructs a new QScriptValue with the boolean \a value and
registers it with the script \a engine.
*/
-QScriptValue::QScriptValue(QScriptEngine *engine, bool val)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
{
- d_ptr->initFrom(JSC::jsBoolean(val));
+ if (engine) {
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ } else {
+ d_ptr = new QScriptValuePrivate(value);
+ }
}
/*!
- \fn QScriptValue::QScriptValue(QScriptEngine *engine, int value)
\obsolete
Constructs a new QScriptValue with the integer \a value and
registers it with the script \a engine.
*/
-QScriptValue::QScriptValue(QScriptEngine *engine, int val)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptEngine* engine, int value)
{
if (engine) {
- QScript::APIShim shim(d_ptr->engine);
- JSC::ExecState *exec = d_ptr->engine->currentFrame;
- d_ptr->initFrom(JSC::jsNumber(exec, val));
- } else
- d_ptr->initFrom(val);
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ } else {
+ d_ptr = new QScriptValuePrivate(value);
+ }
}
/*!
- \fn QScriptValue::QScriptValue(QScriptEngine *engine, uint 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 val)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
{
if (engine) {
- QScript::APIShim shim(d_ptr->engine);
- JSC::ExecState *exec = d_ptr->engine->currentFrame;
- d_ptr->initFrom(JSC::jsNumber(exec, val));
- } else
- d_ptr->initFrom(val);
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ } else {
+ d_ptr = new QScriptValuePrivate(value);
+ }
}
/*!
- \fn QScriptValue::QScriptValue(QScriptEngine *engine, qsreal value)
\obsolete
Constructs a new QScriptValue with the qsreal \a value and
registers it with the script \a engine.
*/
-QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
{
if (engine) {
- QScript::APIShim shim(d_ptr->engine);
- JSC::ExecState *exec = d_ptr->engine->currentFrame;
- d_ptr->initFrom(JSC::jsNumber(exec, val));
- } else
- d_ptr->initFrom(val);
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ } else {
+ d_ptr = new QScriptValuePrivate(value);
+ }
}
/*!
- \fn QScriptValue::QScriptValue(QScriptEngine *engine, const QString &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 &val)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
{
if (engine) {
- QScript::APIShim shim(d_ptr->engine);
- JSC::ExecState *exec = d_ptr->engine->currentFrame;
- d_ptr->initFrom(JSC::jsString(exec, val));
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
} else {
- d_ptr->initFrom(val);
+ d_ptr = new QScriptValuePrivate(value);
}
}
/*!
- \fn QScriptValue::QScriptValue(QScriptEngine *engine, const char *value)
\obsolete
Constructs a new QScriptValue with the string \a value and
registers it with the script \a engine.
*/
-
-#ifndef QT_NO_CAST_FROM_ASCII
-QScriptValue::QScriptValue(QScriptEngine *engine, const char *val)
- : d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
{
if (engine) {
- QScript::APIShim shim(d_ptr->engine);
- JSC::ExecState *exec = d_ptr->engine->currentFrame;
- d_ptr->initFrom(JSC::jsString(exec, val));
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), QString::fromUtf8(value));
} else {
- d_ptr->initFrom(QString::fromAscii(val));
+ d_ptr = new QScriptValuePrivate(QString::fromUtf8(value));
}
}
-#endif
/*!
- \since 4.5
-
- Constructs a new QScriptValue with a special \a value.
-*/
-QScriptValue::QScriptValue(SpecialValue value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
-{
- switch (value) {
- case NullValue:
- d_ptr->initFrom(JSC::jsNull());
- break;
- case UndefinedValue:
- d_ptr->initFrom(JSC::jsUndefined());
- break;
- }
-}
-
-/*!
- \since 4.5
-
- Constructs a new QScriptValue with a boolean \a value.
-*/
-QScriptValue::QScriptValue(bool value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
-{
- d_ptr->initFrom(JSC::jsBoolean(value));
-}
-
-/*!
- \since 4.5
-
- Constructs a new QScriptValue with a number \a value.
-*/
-QScriptValue::QScriptValue(int value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
-{
- d_ptr->initFrom(value);
-}
-
-/*!
- \since 4.5
+ \obsolete
- Constructs a new QScriptValue with a number \a value.
+ Constructs a new QScriptValue with the special \a value and
+ registers it with the script \a engine.
*/
-QScriptValue::QScriptValue(uint value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value)
{
- d_ptr->initFrom(value);
+ if (engine) {
+ QScriptIsolate api(QScriptEnginePrivate::get(engine), QScriptIsolate::NotNullEngine);
+ d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+ } else {
+ d_ptr = new QScriptValuePrivate(value);
+ }
}
/*!
- \since 4.5
+ Constructs a new QScriptValue that is a copy of \a other.
- Constructs a new QScriptValue with a number \a value.
+ 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(qsreal value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+QScriptValue::QScriptValue(const QScriptValue& other)
+ : d_ptr(other.d_ptr)
{
- d_ptr->initFrom(value);
}
/*!
- \since 4.5
-
- Constructs a new QScriptValue with a string \a value.
+ Destroys this QScriptValue.
*/
-QScriptValue::QScriptValue(const QString &value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+QScriptValue::~QScriptValue()
{
- d_ptr->initFrom(value);
}
/*!
- \since 4.5
-
- Constructs a new QScriptValue with a string \a value.
+ Returns true if this QScriptValue is valid; otherwise returns
+ false.
*/
-QScriptValue::QScriptValue(const QLatin1String &value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+bool QScriptValue::isValid() const
{
- d_ptr->initFrom(value);
+ Q_D(const QScriptValue);
+ QScriptIsolate api(d->engine());
+ return d->isValid();
}
/*!
- \since 4.5
+ Returns true if this QScriptValue is of the primitive type Boolean;
+ otherwise returns false.
- Constructs a new QScriptValue with a string \a value.
+ \sa toBool()
*/
-
-#ifndef QT_NO_CAST_FROM_ASCII
-QScriptValue::QScriptValue(const char *value)
- : d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+bool QScriptValue::isBool() const
{
- d_ptr->initFrom(QString::fromAscii(value));
+ Q_D(const QScriptValue);
+ QScriptIsolate api(d->engine());
+ return d->isBool();
}
-#endif
/*!
- 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;
-}
+ \obsolete
-/*!
- Returns true if this QScriptValue is an object of the Error class;
+ Use isBool() instead.
+ Returns true if this QScriptValue is of the primitive type Boolean;
otherwise returns false.
-
- \sa QScriptContext::throwError()
*/
-bool QScriptValue::isError() const
+bool QScriptValue::isBoolean() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isError(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->isBool();
}
/*!
- Returns true if this QScriptValue is an object of the Array class;
+ Returns true if this QScriptValue is of the primitive type Number;
otherwise returns false.
- \sa QScriptEngine::newArray()
+ \sa toNumber()
*/
-bool QScriptValue::isArray() const
+bool QScriptValue::isNumber() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isArray(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->isNumber();
}
/*!
- Returns true if this QScriptValue is an object of the Date class;
+ Returns true if this QScriptValue is of the primitive type Null;
otherwise returns false.
- \sa QScriptEngine::newDate()
+ \sa QScriptEngine::nullValue()
*/
-bool QScriptValue::isDate() const
+bool QScriptValue::isNull() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isDate(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->isNull();
}
/*!
- Returns true if this QScriptValue is an object of the RegExp class;
+ Returns true if this QScriptValue is of the primitive type String;
otherwise returns false.
- \sa QScriptEngine::newRegExp()
+ \sa toString()
*/
-bool QScriptValue::isRegExp() const
+bool QScriptValue::isString() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isRegExp(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->isString();
}
/*!
- If this QScriptValue is an object, returns the internal prototype
- (\c{__proto__} property) of this object; otherwise returns an
- invalid QScriptValue.
+ Returns true if this QScriptValue is of the primitive type Undefined;
+ otherwise returns false.
- \sa setPrototype(), isObject()
+ \sa QScriptEngine::undefinedValue()
*/
-QScriptValue QScriptValue::prototype() const
+bool QScriptValue::isUndefined() const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- return d->engine->scriptValueFromJSCValue(JSC::asObject(d->jscValue)->prototype());
+ QScriptIsolate api(d->engine());
+ return d->isUndefined();
}
/*!
- 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)
-{
- Q_D(QScriptValue);
- if (!d || !d->isObject())
- return;
-
- JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype);
- if (!other || !(other.isObject() || other.isNull()))
- return;
-
- if (QScriptValuePrivate::getEngine(prototype)
- && (QScriptValuePrivate::getEngine(prototype) != d->engine)) {
- qWarning("QScriptValue::setPrototype() failed: "
- "cannot set a prototype created in "
- "a different engine");
- return;
- }
- JSC::JSObject *thisObject = JSC::asObject(d->jscValue);
-
- // check for cycle
- JSC::JSValue nextPrototypeValue = other;
- while (nextPrototypeValue && nextPrototypeValue.isObject()) {
- JSC::JSObject *nextPrototype = JSC::asObject(nextPrototypeValue);
- if (nextPrototype == thisObject) {
- qWarning("QScriptValue::setPrototype() failed: cyclic prototype value");
- return;
- }
- nextPrototypeValue = nextPrototype->prototype();
- }
-
- thisObject->setPrototype(other);
-
- // Sync the internal Global Object prototype if appropriate.
- if (((thisObject == d->engine->originalGlobalObjectProxy)
- && !d->engine->customGlobalObject())
- || (thisObject == d->engine->customGlobalObject())) {
- d->engine->originalGlobalObject()->setPrototype(other);
- }
-}
+ Returns true if this QScriptValue is an object of the Error class;
+ otherwise returns false.
-/*!
- \internal
+ \sa QScriptContext::throwError()
*/
-QScriptValue QScriptValue::scope() const
+bool QScriptValue::isError() const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- // ### make hidden property
- JSC::JSValue result = d->property("__qt_scope__", QScriptValue::ResolveLocal);
- return d->engine->scriptValueFromJSCValue(result);
-}
-
-/*!
- \internal
-*/
-void QScriptValue::setScope(const QScriptValue &scope)
-{
- Q_D(QScriptValue);
- if (!d || !d->isObject())
- return;
- if (scope.isValid() && QScriptValuePrivate::getEngine(scope)
- && (QScriptValuePrivate::getEngine(scope) != d->engine)) {
- qWarning("QScriptValue::setScope() failed: "
- "cannot set a scope object created in "
- "a different engine");
- return;
- }
- JSC::JSValue other = d->engine->scriptValueToJSCValue(scope);
- JSC::ExecState *exec = d->engine->currentFrame;
- JSC::Identifier id = JSC::Identifier(exec, "__qt_scope__");
- if (!scope.isValid()) {
- JSC::asObject(d->jscValue)->removeDirect(id);
- } else {
- // ### make hidden property
- JSC::asObject(d->jscValue)->putDirect(id, other);
- }
+ QScriptIsolate api(d->engine());
+ return d->isError();
}
/*!
- Returns true if this QScriptValue is an instance of
- \a other; otherwise returns false.
+ Returns true if this QScriptValue is an object of the Array class;
+ 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.
+ \sa QScriptEngine::newArray()
*/
-bool QScriptValue::instanceOf(const QScriptValue &other) const
+bool QScriptValue::isArray() const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject() || !other.isObject())
- return false;
- if (QScriptValuePrivate::getEngine(other) != d->engine) {
- qWarning("QScriptValue::instanceof: "
- "cannot perform operation on a value created in "
- "a different engine");
- return false;
- }
- JSC::JSValue jscProto = d->engine->scriptValueToJSCValue(other.property(QLatin1String("prototype")));
- if (!jscProto)
- jscProto = JSC::jsUndefined();
- JSC::ExecState *exec = d->engine->currentFrame;
- JSC::JSValue jscOther = d->engine->scriptValueToJSCValue(other);
- return JSC::asObject(jscOther)->hasInstance(exec, d->jscValue, jscProto);
-}
-
-// ### move
-
-namespace QScript
-{
-
-enum Type {
- Undefined,
- Null,
- Boolean,
- String,
- Number,
- Object
-};
-
-static Type type(const QScriptValue &v)
-{
- if (v.isUndefined())
- return Undefined;
- else if (v.isNull())
- return Null;
- else if (v.isBoolean())
- return Boolean;
- else if (v.isString())
- return String;
- else if (v.isNumber())
- return Number;
- Q_ASSERT(v.isObject());
- return Object;
-}
-
-static QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference)
-{
- Q_ASSERT(object.isObject());
- QScriptValuePrivate *pp = QScriptValuePrivate::get(object);
- Q_ASSERT(pp->engine != 0);
- QScript::APIShim shim(pp->engine);
- JSC::ExecState *exec = pp->engine->currentFrame;
- JSC::JSValue savedException;
- QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint);
- QScriptEnginePrivate::restoreException(exec, savedException);
- return pp->engine->scriptValueFromJSCValue(result);
-}
-
-static bool IsNumerical(const QScriptValue &value)
-{
- return value.isNumber() || value.isBool();
-}
-
-static bool LessThan(QScriptValue lhs, QScriptValue rhs)
-{
- if (type(lhs) == type(rhs)) {
- switch (type(lhs)) {
- case Undefined:
- case Null:
- return false;
-
- case Number:
- return lhs.toNumber() < rhs.toNumber();
-
- case Boolean:
- return lhs.toBool() < rhs.toBool();
-
- case String:
- return lhs.toString() < rhs.toString();
-
- case Object:
- break;
- } // switch
- }
-
- if (lhs.isObject())
- lhs = ToPrimitive(lhs, JSC::PreferNumber);
-
- if (rhs.isObject())
- rhs = ToPrimitive(rhs, JSC::PreferNumber);
-
- if (lhs.isString() && rhs.isString())
- return lhs.toString() < rhs.toString();
-
- return lhs.toNumber() < rhs.toNumber();
-}
-
-static bool Equals(QScriptValue lhs, QScriptValue rhs)
-{
- if (type(lhs) == type(rhs)) {
- switch (type(lhs)) {
- case QScript::Undefined:
- case QScript::Null:
- return true;
-
- case QScript::Number:
- return lhs.toNumber() == rhs.toNumber();
-
- case QScript::Boolean:
- return lhs.toBool() == rhs.toBool();
-
- case QScript::String:
- return lhs.toString() == rhs.toString();
-
- case QScript::Object:
- if (lhs.isVariant())
- return lhs.strictlyEquals(rhs) || (lhs.toVariant() == rhs.toVariant());
-#ifndef QT_NO_QOBJECT
- else if (lhs.isQObject())
- return (lhs.strictlyEquals(rhs)) || (lhs.toQObject() == rhs.toQObject());
-#endif
- else
- return lhs.strictlyEquals(rhs);
- }
- }
-
- if (lhs.isNull() && rhs.isUndefined())
- return true;
-
- else if (lhs.isUndefined() && rhs.isNull())
- return true;
-
- else if (IsNumerical(lhs) && rhs.isString())
- return lhs.toNumber() == rhs.toNumber();
-
- else if (lhs.isString() && IsNumerical(rhs))
- return lhs.toNumber() == rhs.toNumber();
-
- else if (lhs.isBool())
- return Equals(lhs.toNumber(), rhs);
-
- else if (rhs.isBool())
- return Equals(lhs, rhs.toNumber());
-
- else if (lhs.isObject() && !rhs.isNull()) {
- lhs = ToPrimitive(lhs);
-
- if (lhs.isValid() && !lhs.isObject())
- return Equals(lhs, rhs);
- }
-
- else if (rhs.isObject() && ! lhs.isNull()) {
- rhs = ToPrimitive(rhs);
- if (rhs.isValid() && !rhs.isObject())
- return Equals(lhs, rhs);
- }
-
- return false;
-}
-
-} // namespace QScript
+ QScriptIsolate api(d->engine());
+ return d->isArray();
+ }
/*!
- Returns true if this QScriptValue is less than \a other, otherwise
- returns false. The comparison follows the behavior described in
- \l{ECMA-262} section 11.8.5, "The Abstract Relational Comparison
- Algorithm".
+ Returns true if this QScriptValue is of the Object type; otherwise
+ returns false.
- 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).
+ Note that function values, variant values, and QObject values are
+ objects, so this function returns true for such values.
- \sa equals()
+ \sa toObject(), QScriptEngine::newObject()
*/
-bool QScriptValue::lessThan(const QScriptValue &other) const
+bool QScriptValue::isObject() const
{
Q_D(const QScriptValue);
- // no equivalent function in JSC? There's a jsLess() in VM/Machine.cpp
- if (!isValid() || !other.isValid())
- return false;
- if (QScriptValuePrivate::getEngine(other) && d->engine
- && (QScriptValuePrivate::getEngine(other) != d->engine)) {
- qWarning("QScriptValue::lessThan: "
- "cannot compare to a value created in "
- "a different engine");
- return false;
- }
- return QScript::LessThan(*this, other);
+ QScriptIsolate api(d->engine());
+ return d->isObject();
}
/*!
- 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).
+ Returns true if this QScriptValue is a function; otherwise returns
+ false.
- \sa strictlyEquals(), lessThan()
+ \sa call()
*/
-bool QScriptValue::equals(const QScriptValue &other) const
+bool QScriptValue::isFunction() const
{
Q_D(const QScriptValue);
- if (!d || !other.d_ptr)
- return (d_ptr == other.d_ptr);
- if (QScriptValuePrivate::getEngine(other) && d->engine
- && (QScriptValuePrivate::getEngine(other) != d->engine)) {
- qWarning("QScriptValue::equals: "
- "cannot compare to a value created in "
- "a different engine");
- return false;
- }
- if (d->isJSC() && other.d_ptr->isJSC()) {
- QScriptEnginePrivate *eng_p = d->engine;
- if (!eng_p)
- eng_p = other.d_ptr->engine;
- if (eng_p) {
- QScript::APIShim shim(eng_p);
- JSC::ExecState *exec = eng_p->currentFrame;
- JSC::JSValue savedException;
- QScriptEnginePrivate::saveException(exec, &savedException);
- bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue);
- QScriptEnginePrivate::restoreException(exec, savedException);
- return result;
- }
- }
- return QScript::Equals(*this, other);
+ QScriptIsolate api(d->engine());
+ return d->isCallable();
}
/*!
- 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
+ Returns true if this QScriptValue is a variant value;
+ otherwise returns false.
- \sa equals()
+ \sa toVariant(), QScriptEngine::newVariant()
*/
-bool QScriptValue::strictlyEquals(const QScriptValue &other) const
+bool QScriptValue::isVariant() const
{
Q_D(const QScriptValue);
- if (!d || !other.d_ptr)
- return (d_ptr == other.d_ptr);
- if (QScriptValuePrivate::getEngine(other) && d->engine
- && (QScriptValuePrivate::getEngine(other) != d->engine)) {
- qWarning("QScriptValue::strictlyEquals: "
- "cannot compare to a value created in "
- "a different engine");
- return false;
- }
-
- if (d->type != other.d_ptr->type) {
- if (d->type == QScriptValuePrivate::JavaScriptCore) {
- QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
- if (eng_p)
- return JSC::JSValue::strictEqual(eng_p->currentFrame, d->jscValue, eng_p->scriptValueToJSCValue(other));
- } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) {
- QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine;
- if (eng_p)
- return JSC::JSValue::strictEqual(eng_p->currentFrame, eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
- }
-
- return false;
- }
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine;
- JSC::ExecState *exec = eng_p ? eng_p->currentFrame : 0;
- return JSC::JSValue::strictEqual(exec, d->jscValue, other.d_ptr->jscValue);
- }
- case QScriptValuePrivate::Number:
- return (d->numberValue == other.d_ptr->numberValue);
- case QScriptValuePrivate::String:
- return (d->stringValue == other.d_ptr->stringValue);
- }
- return false;
+ QScriptIsolate api(d->engine());
+ return d->isVariant();
}
/*!
@@ -947,22 +462,8 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const
QString QScriptValue::toString() const
{
Q_D(const QScriptValue);
- if (!d)
- return QString();
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toString(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toString(0, d->jscValue);
- } }
- case QScriptValuePrivate::Number:
- return QScript::ToString(d->numberValue);
- case QScriptValuePrivate::String:
- return d->stringValue;
- }
- return QString();
+ QScriptIsolate api(d->engine());
+ return d->toString();
}
/*!
@@ -980,23 +481,27 @@ QString QScriptValue::toString() const
qsreal QScriptValue::toNumber() const
{
Q_D(const QScriptValue);
- if (!d)
- return 0;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toNumber(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toNumber(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return d->numberValue;
- case QScriptValuePrivate::String:
- return QScript::ToNumber(d->stringValue);
- }
- return 0;
+ QScriptIsolate api(d->engine());
+ return d->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
+{
+ Q_D(const QScriptValue);
+ QScriptIsolate api(d->engine());
+ return d->toBool();
}
/*!
@@ -1007,30 +512,13 @@ qsreal QScriptValue::toNumber() const
bool QScriptValue::toBoolean() const
{
Q_D(const QScriptValue);
- if (!d)
- return false;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toBool(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QScript::ToBool(d->numberValue);
- case QScriptValuePrivate::String:
- return QScript::ToBool(d->stringValue);
- }
- return false;
+ QScriptIsolate api(d->engine());
+ return d->toBool();
}
/*!
- \since 4.5
-
- Returns the boolean value of this QScriptValue, using the conversion
- rules described in \l{ECMA-262} section 9.2, "ToBoolean".
+ 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
@@ -1038,28 +526,13 @@ bool QScriptValue::toBoolean() const
attempt to convert the object to a primitive value (possibly
resulting in an uncaught script exception).
- \sa isBool()
+ \sa toNumber()
*/
-bool QScriptValue::toBool() const
+qsreal QScriptValue::toInteger() const
{
Q_D(const QScriptValue);
- if (!d)
- return false;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toBool(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QScript::ToBool(d->numberValue);
- case QScriptValuePrivate::String:
- return QScript::ToBool(d->stringValue);
- }
- return false;
+ QScriptIsolate api(d->engine());
+ return d->toInteger();
}
/*!
@@ -1077,23 +550,8 @@ bool QScriptValue::toBool() const
qint32 QScriptValue::toInt32() const
{
Q_D(const QScriptValue);
- if (!d)
- return 0;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toInt32(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toInt32(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QScript::ToInt32(d->numberValue);
- case QScriptValuePrivate::String:
- return QScript::ToInt32(d->stringValue);
- }
- return 0;
+ QScriptIsolate api(d->engine());
+ return d->toInt32();
}
/*!
@@ -1111,23 +569,8 @@ qint32 QScriptValue::toInt32() const
quint32 QScriptValue::toUInt32() const
{
Q_D(const QScriptValue);
- if (!d)
- return 0;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toUInt32(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toUInt32(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QScript::ToUInt32(d->numberValue);
- case QScriptValuePrivate::String:
- return QScript::ToUInt32(d->stringValue);
- }
- return 0;
+ QScriptIsolate api(d->engine());
+ return d->toUInt32();
}
/*!
@@ -1145,57 +588,20 @@ quint32 QScriptValue::toUInt32() const
quint16 QScriptValue::toUInt16() const
{
Q_D(const QScriptValue);
- if (!d)
- return 0;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toUInt16(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toUInt16(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QScript::ToUInt16(d->numberValue);
- case QScriptValuePrivate::String:
- return QScript::ToUInt16(d->stringValue);
- }
- return 0;
+ QScriptIsolate api(d->engine());
+ return d->toUInt16();
}
/*!
- 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).
+ \obsolete
- \sa toNumber()
+ This function is obsolete; use QScriptEngine::toObject() instead.
*/
-qsreal QScriptValue::toInteger() const
+QScriptValue QScriptValue::toObject() const
{
Q_D(const QScriptValue);
- if (!d)
- return 0;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toInteger(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toInteger(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QScript::ToInteger(d->numberValue);
- case QScriptValuePrivate::String:
- return QScript::ToInteger(d->stringValue);
- }
- return 0;
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->toObject());
}
/*!
@@ -1223,751 +629,522 @@ qsreal QScriptValue::toInteger() const
QVariant QScriptValue::toVariant() const
{
Q_D(const QScriptValue);
- if (!d)
- return QVariant();
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore: {
- if (d->engine) {
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toVariant(d->engine->currentFrame, d->jscValue);
- } else {
- return QScriptEnginePrivate::toVariant(0, d->jscValue);
- }
- }
- case QScriptValuePrivate::Number:
- return QVariant(d->numberValue);
- case QScriptValuePrivate::String:
- return QVariant(d->stringValue);
- }
- return QVariant();
+ QScriptIsolate api(d->engine());
+ QScriptDeclarativeClass *cls = QScriptDeclarativeClassObject::declarativeClass(d);
+ if (cls)
+ return cls->toVariant(QScriptDeclarativeClassObject::object(d));
+ return d->toVariant();
}
+
/*!
- \obsolete
+ 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.
- This function is obsolete; use QScriptEngine::toObject() instead.
+ 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::toObject() const
+QScriptValue QScriptValue::call(const QScriptValue& thisObject, const QScriptValueList& args)
{
- Q_D(const QScriptValue);
- if (!d || !d->engine)
- return QScriptValue();
- return engine()->toObject(*this);
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ return d->call(QScriptValuePrivate::get(thisObject), args);
}
/*!
- 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.
+ Calls this QScriptValue as a function, using \a thisObject as
+ the `this' object in the function call, and passing \a arguments
+ as arguments to the function. Returns the value returned from
+ the function.
- \sa isDate()
+ If this QScriptValue is not a function, call() does nothing
+ and returns an invalid QScriptValue.
+
+ \a arguments can be an arguments object, an array, null or
+ undefined; any other type will cause a TypeError to be thrown.
+
+ Note that if \a thisObject is not an object, the global object
+ (see \l{QScriptEngine::globalObject()}) will be used as the
+ `this' object.
+
+ One common usage of this function is to forward native function
+ calls to another function:
+
+ \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 3
+
+ \sa construct(), QScriptContext::argumentsObject()
*/
-QDateTime QScriptValue::toDateTime() const
+QScriptValue QScriptValue::call(const QScriptValue &thisObject, const QScriptValue &arguments)
{
- Q_D(const QScriptValue);
- if (!d || !d->engine)
- return QDateTime();
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue);
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ return d->call(QScriptValuePrivate::get(thisObject), arguments);
}
-#ifndef QT_NO_REGEXP
/*!
- Returns the QRegExp representation of this value.
- If this QScriptValue is not a regular expression, an empty
- QRegExp is returned.
+ Creates a new \c{Object} and calls this QScriptValue as a
+ constructor, using the created object as the `this' object and
+ passing \a args as arguments. If the return value from the
+ constructor call is an object, then that object is returned;
+ otherwise the default constructed object is returned.
- \sa isRegExp()
+ If this QScriptValue is not a function, construct() does nothing
+ and returns an invalid QScriptValue.
+
+ Calling construct() can cause an exception to occur in the script
+ engine; in that case, construct() returns the value that was thrown
+ (typically an \c{Error} object). You can call
+ QScriptEngine::hasUncaughtException() to determine if an exception
+ occurred.
+
+ \sa call(), QScriptEngine::newObject()
*/
-QRegExp QScriptValue::toRegExp() const
+QScriptValue QScriptValue::construct(const QScriptValueList &args)
{
- Q_D(const QScriptValue);
- if (!d || !d->engine)
- return QRegExp();
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue);
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->construct(args));
}
-#endif // QT_NO_REGEXP
/*!
- If this QScriptValue is a QObject, returns the QObject pointer
- that the QScriptValue represents; otherwise, returns 0.
+ Creates a new \c{Object} and calls this QScriptValue as a
+ constructor, using the created object as the `this' object and
+ passing \a arguments as arguments. If the return value from the
+ constructor call is an object, then that object is returned;
+ otherwise the default constructed object is returned.
+
+ If this QScriptValue is not a function, construct() does nothing
+ and returns an invalid QScriptValue.
- If the QObject that this QScriptValue wraps has been deleted,
- this function returns 0 (i.e. it is possible for toQObject()
- to return 0 even when isQObject() returns true).
+ \a arguments can be an arguments object, an array, null or
+ undefined. Any other type will cause a TypeError to be thrown.
- \sa isQObject()
+ \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject()
*/
-QObject *QScriptValue::toQObject() const
+QScriptValue QScriptValue::construct(const QScriptValue &arguments)
{
- Q_D(const QScriptValue);
- if (!d || !d->engine)
- return 0;
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue);
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->construct(arguments));
}
-/*!
- If this QScriptValue is a QMetaObject, returns the QMetaObject pointer
- that the QScriptValue represents; otherwise, returns 0.
- \sa isQMetaObject()
+/*!
+ Returns the QScriptEngine that created this QScriptValue,
+ or 0 if this QScriptValue is invalid or the value is not
+ associated with a particular engine.
*/
-const QMetaObject *QScriptValue::toQMetaObject() const
+QScriptEngine* QScriptValue::engine() const
{
Q_D(const QScriptValue);
- if (!d || !d->engine)
- return 0;
- QScript::APIShim shim(d->engine);
- return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue);
+ QScriptIsolate api(d->engine());
+ QScriptEnginePrivate* engine = d->engine();
+ if (engine)
+ return QScriptEnginePrivate::get(engine);
+ return 0;
}
/*!
- 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.
+ If this QScriptValue is an object, returns the internal prototype
+ (\c{__proto__} property) of this object; otherwise returns an
+ invalid QScriptValue.
- \sa property()
+ \sa setPrototype(), isObject()
*/
-
-void QScriptValue::setProperty(const QString &name, const QScriptValue &value,
- const PropertyFlags &flags)
+QScriptValue QScriptValue::prototype() const
{
- Q_D(QScriptValue);
- if (!d || !d->isObject())
- return;
- QScript::APIShim shim(d->engine);
- QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
- if (valueEngine && (valueEngine != d->engine)) {
- qWarning("QScriptValue::setProperty(%s) failed: "
- "cannot set value created in a different engine",
- qPrintable(name));
- return;
- }
- JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
- d->setProperty(name, jsValue, flags);
+ Q_D(const QScriptValue);
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->prototype());
}
/*!
- 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 this QScriptValue is an object, sets the internal prototype
+ (\c{__proto__} property) of this object to be \a prototype;
+ otherwise does nothing.
- 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).
+ 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 setProperty(), propertyFlags(), QScriptValueIterator
+ \sa prototype(), isObject()
*/
-QScriptValue QScriptValue::property(const QString &name,
- const ResolveFlags &mode) const
+void QScriptValue::setPrototype(const QScriptValue& prototype)
{
- Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- return d->engine->scriptValueFromJSCValue(d->property(name, mode));
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ d->setPrototype(QScriptValuePrivate::get(prototype));
}
/*!
- \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.
+ Assigns the \a other value to this QScriptValue.
- If this QScriptValue is not an Array object, this function behaves
- as if property() was called with the string representation of \a
- arrayIndex.
+ 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::property(quint32 arrayIndex,
- const ResolveFlags &mode) const
+QScriptValue& QScriptValue::operator=(const QScriptValue& other)
{
- Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode));
+ d_ptr = other.d_ptr;
+ return *this;
}
/*!
- \overload
+ 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".
- Sets the property at the given \a arrayIndex to the given \a value.
+ 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().
- This function is provided for convenience and performance when
- working with array objects.
+ 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).
- If this QScriptValue is not an Array object, this function behaves
- as if setProperty() was called with the string representation of \a
- arrayIndex.
+ \sa strictlyEquals(), lessThan()
*/
-void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value,
- const PropertyFlags &flags)
+bool QScriptValue::equals(const QScriptValue& other) const
{
- Q_D(QScriptValue);
- if (!d || !d->isObject())
- return;
- if (QScriptValuePrivate::getEngine(value)
- && (QScriptValuePrivate::getEngine(value) != d->engine)) {
- qWarning("QScriptValue::setProperty() failed: "
- "cannot set value created in a different engine");
- return;
- }
- QScript::APIShim shim(d->engine);
- JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
- d->setProperty(arrayIndex, jsValue, flags);
+ Q_D(const QScriptValue);
+ QScriptValuePrivate* otherValue = QScriptValuePrivate::get(other);
+ QScriptIsolate api(d->engine() ? d->engine() : otherValue->engine());
+ return d_ptr->equals(otherValue);
}
/*!
- \since 4.4
+ 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".
- Returns the value of this QScriptValue's property with the given \a name,
- using the given \a mode to resolve the property.
+ 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:
- 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.
+ \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 QScriptEngine::toStringHandle(), setProperty()
+ \sa equals()
*/
-QScriptValue QScriptValue::property(const QScriptString &name,
- const ResolveFlags &mode) const
+bool QScriptValue::strictlyEquals(const QScriptValue& other) const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- return d->engine->scriptValueFromJSCValue(d->property(name.d_ptr->identifier, mode));
+ QScriptValuePrivate* o = QScriptValuePrivate::get(other);
+ QScriptIsolate api(d->engine() ? d->engine() : o->engine());
+ return d_ptr->strictlyEquals(o);
}
/*!
- \since 4.4
-
- 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.
+ Returns true if this QScriptValue is less than \a other, otherwise
+ returns false. The comparison follows the behavior described in
+ \l{ECMA-262} section 11.8.5, "The Abstract Relational Comparison
+ Algorithm".
- 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.
+ 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 QScriptEngine::toStringHandle()
+ \sa equals()
*/
-void QScriptValue::setProperty(const QScriptString &name,
- const QScriptValue &value,
- const PropertyFlags &flags)
+bool QScriptValue::lessThan(const QScriptValue &other) const
{
- Q_D(QScriptValue);
- if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
- return;
- QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
- if (valueEngine && (valueEngine != d->engine)) {
- qWarning("QScriptValue::setProperty(%s) failed: "
- "cannot set value created in a different engine",
- qPrintable(name.toString()));
- return;
- }
- QScript::APIShim shim(d->engine);
- JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
- d->setProperty(name.d_ptr->identifier, jsValue, flags);
+ Q_D(const QScriptValue);
+ QScriptValuePrivate *o = QScriptValuePrivate::get(other);
+ QScriptIsolate api(d->engine() ? d->engine() : o->engine());
+ return d->lessThan(o);
}
/*!
- Returns the flags of the property with the given \a name, using the
- given \a mode to resolve the property.
+ Returns true if this QScriptValue is an instance of
+ \a other; otherwise returns false.
- \sa property()
+ 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.
*/
-QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString &name,
- const ResolveFlags &mode) const
+bool QScriptValue::instanceOf(const QScriptValue &other) const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return 0;
- QScript::APIShim shim(d->engine);
- JSC::ExecState *exec = d->engine->currentFrame;
- return d->propertyFlags(JSC::Identifier(exec, name), mode);
-
+ QScriptIsolate api(d->engine());
+ return d->instanceOf(QScriptValuePrivate::get(other));
}
/*!
- \since 4.4
+ Returns the value of this QScriptValue's property with the given \a name,
+ using the given \a mode to resolve the property.
- Returns the flags of the 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.
- \sa property()
+ 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::PropertyFlags QScriptValue::propertyFlags(const QScriptString &name,
- const ResolveFlags &mode) const
+QScriptValue QScriptValue::property(const QString& name, const ResolveFlags& mode) const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
- return 0;
- return d->propertyFlags(name.d_ptr->identifier, mode);
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->property(name, mode));
}
/*!
- 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.
+ \overload
- 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.
+ Returns the value of this QScriptValue's property with the given \a name,
+ using the given \a mode to resolve the property.
- \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2
+ 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 construct()
+ \sa QScriptEngine::toStringHandle(), setProperty()
*/
-QScriptValue QScriptValue::call(const QScriptValue &thisObject,
- const QScriptValueList &args)
+QScriptValue QScriptValue::property(const QScriptString& name, const ResolveFlags& mode) const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- JSC::JSValue callee = d->jscValue;
- JSC::CallData callData;
- JSC::CallType callType = callee.getCallData(callData);
- if (callType == JSC::CallTypeNone)
- return QScriptValue();
-
- if (QScriptValuePrivate::getEngine(thisObject)
- && (QScriptValuePrivate::getEngine(thisObject) != d->engine)) {
- qWarning("QScriptValue::call() failed: "
- "cannot call function with thisObject created in "
- "a different engine");
- return QScriptValue();
- }
-
- JSC::ExecState *exec = d->engine->currentFrame;
-
- JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject);
- if (!jscThisObject || !jscThisObject.isObject())
- jscThisObject = d->engine->globalObject();
-
- QVarLengthArray<JSC::JSValue, 8> argsVector(args.size());
- for (int i = 0; i < args.size(); ++i) {
- const QScriptValue &arg = args.at(i);
- if (!arg.isValid()) {
- argsVector[i] = JSC::jsUndefined();
- } else if (QScriptValuePrivate::getEngine(arg)
- && (QScriptValuePrivate::getEngine(arg) != d->engine)) {
- qWarning("QScriptValue::call() failed: "
- "cannot call function with argument created in "
- "a different engine");
- return QScriptValue();
- } else {
- argsVector[i] = d->engine->scriptValueToJSCValue(arg);
- }
- }
- JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
-
- JSC::JSValue savedException;
- QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs);
- if (exec->hadException()) {
- result = exec->exception();
- } else {
- QScriptEnginePrivate::restoreException(exec, savedException);
- }
- return d->engine->scriptValueFromJSCValue(result);
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->property(QScriptStringPrivate::get(name), mode));
}
/*!
- Calls this QScriptValue as a function, using \a thisObject as
- the `this' object in the function call, and passing \a arguments
- 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.
-
- \a arguments can be an arguments object, an array, null or
- undefined; any other type will cause a TypeError to be thrown.
-
- Note that if \a thisObject is not an object, the global object
- (see \l{QScriptEngine::globalObject()}) will be used as the
- `this' object.
+ \overload
- One common usage of this function is to forward native function
- calls to another function:
+ Returns the property at the given \a arrayIndex, using the given \a
+ mode to resolve the property.
- \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 3
+ This function is provided for convenience and performance when
+ working with array objects.
- \sa construct(), QScriptContext::argumentsObject()
+ 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::call(const QScriptValue &thisObject,
- const QScriptValue &arguments)
+QScriptValue QScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode) const
{
- Q_D(QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- JSC::JSValue callee = d->jscValue;
- JSC::CallData callData;
- JSC::CallType callType = callee.getCallData(callData);
- if (callType == JSC::CallTypeNone)
- return QScriptValue();
-
- if (QScriptValuePrivate::getEngine(thisObject)
- && (QScriptValuePrivate::getEngine(thisObject) != d->engine)) {
- qWarning("QScriptValue::call() failed: "
- "cannot call function with thisObject created in "
- "a different engine");
- return QScriptValue();
- }
-
- JSC::ExecState *exec = d->engine->currentFrame;
+ Q_D(const QScriptValue);
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->property(arrayIndex, mode));
+}
- JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject);
- if (!jscThisObject || !jscThisObject.isObject())
- jscThisObject = d->engine->globalObject();
+/*!
+ Sets the value of this QScriptValue's property with the given \a name to
+ the given \a value.
- JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments);
- // copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
- JSC::MarkedArgumentBuffer applyArgs;
- if (!array.isUndefinedOrNull()) {
- if (!array.isObject()) {
- return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
- }
- if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
- JSC::asArguments(array)->fillArgList(exec, applyArgs);
- else if (JSC::isJSArray(&exec->globalData(), array))
- JSC::asArray(array)->fillArgList(exec, applyArgs);
- else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) {
- unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
- for (unsigned i = 0; i < length; ++i)
- applyArgs.append(JSC::asArray(array)->get(exec, i));
- } else {
- return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
- }
- }
+ If this QScriptValue is not an object, this function does nothing.
- JSC::JSValue savedException;
- QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs);
- if (exec->hadException()) {
- result = exec->exception();
- } else {
- QScriptEnginePrivate::restoreException(exec, savedException);
- }
- return d->engine->scriptValueFromJSCValue(result);
-}
+ 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.
-/*!
- Creates a new \c{Object} and calls this QScriptValue as a
- constructor, using the created object as the `this' object and
- passing \a args as arguments. If the return value from the
- constructor call is an object, then that object is returned;
- otherwise the default constructed object is returned.
+ If \a value is invalid, the property is removed.
- If this QScriptValue is not a function, construct() does nothing
- and returns an invalid QScriptValue.
+ 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).
- Calling construct() can cause an exception to occur in the script
- engine; in that case, construct() returns the value that was thrown
- (typically an \c{Error} object). You can call
- QScriptEngine::hasUncaughtException() to determine if an exception
- occurred.
+ 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 call(), QScriptEngine::newObject()
+ \sa property()
*/
-QScriptValue QScriptValue::construct(const QScriptValueList &args)
+void QScriptValue::setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags)
{
- Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- JSC::JSValue callee = d->jscValue;
- JSC::ConstructData constructData;
- JSC::ConstructType constructType = callee.getConstructData(constructData);
- if (constructType == JSC::ConstructTypeNone)
- return QScriptValue();
-
- JSC::ExecState *exec = d->engine->currentFrame;
-
- QVarLengthArray<JSC::JSValue, 8> argsVector(args.size());
- for (int i = 0; i < args.size(); ++i) {
- QScriptValue arg = args.at(i);
- if (QScriptValuePrivate::getEngine(arg) != d->engine && QScriptValuePrivate::getEngine(arg)) {
- qWarning("QScriptValue::construct() failed: "
- "cannot construct function with argument created in "
- "a different engine");
- return QScriptValue();
- }
- if (!arg.isValid())
- argsVector[i] = JSC::jsUndefined();
- else
- argsVector[i] = d->engine->scriptValueToJSCValue(args.at(i));
- }
-
- JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
-
- JSC::JSValue savedException;
- QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSValue result;
- JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, jscArgs);
- if (exec->hadException()) {
- result = exec->exception();
- } else {
- result = newObject;
- QScriptEnginePrivate::restoreException(exec, savedException);
- }
- return d->engine->scriptValueFromJSCValue(result);
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ d->setProperty(name, QScriptValuePrivate::get(value), QScriptConverter::toPropertyAttributes(flags));
}
/*!
- Creates a new \c{Object} and calls this QScriptValue as a
- constructor, using the created object as the `this' object and
- passing \a arguments as arguments. If the return value from the
- constructor call is an object, then that object is returned;
- otherwise the default constructed object is returned.
+ \overload
- If this QScriptValue is not a function, construct() does nothing
- and returns an invalid QScriptValue.
+ Sets the property at the given \a arrayIndex to the given \a value.
- \a arguments can be an arguments object, an array, null or
- undefined. Any other type will cause a TypeError to be thrown.
+ This function is provided for convenience and performance when
+ working with array objects.
- \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject()
+ If this QScriptValue is not an Array object, this function behaves
+ as if setProperty() was called with the string representation of \a
+ arrayIndex.
*/
-QScriptValue QScriptValue::construct(const QScriptValue &arguments)
+void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags)
{
Q_D(QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- QScript::APIShim shim(d->engine);
- JSC::JSValue callee = d->jscValue;
- JSC::ConstructData constructData;
- JSC::ConstructType constructType = callee.getConstructData(constructData);
- if (constructType == JSC::ConstructTypeNone)
- return QScriptValue();
-
- JSC::ExecState *exec = d->engine->currentFrame;
-
- if (QScriptValuePrivate::getEngine(arguments) != d->engine && QScriptValuePrivate::getEngine(arguments)) {
- qWarning("QScriptValue::construct() failed: "
- "cannot construct function with argument created in "
- "a different engine");
- return QScriptValue();
- }
- JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments);
- // copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
- JSC::MarkedArgumentBuffer applyArgs;
- if (!array.isUndefinedOrNull()) {
- if (!array.isObject()) {
- return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
- }
- if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
- JSC::asArguments(array)->fillArgList(exec, applyArgs);
- else if (JSC::isJSArray(&exec->globalData(), array))
- JSC::asArray(array)->fillArgList(exec, applyArgs);
- else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) {
- unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
- for (unsigned i = 0; i < length; ++i)
- applyArgs.append(JSC::asArray(array)->get(exec, i));
- } else {
- return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
- }
- }
-
- JSC::JSValue savedException;
- QScriptEnginePrivate::saveException(exec, &savedException);
- JSC::JSValue result;
- JSC::JSObject *newObject = JSC::construct(exec, callee, constructType, constructData, applyArgs);
- if (exec->hadException()) {
- result = exec->exception();
- } else {
- result = newObject;
- QScriptEnginePrivate::restoreException(exec, savedException);
- }
- return d->engine->scriptValueFromJSCValue(result);
+ QScriptIsolate api(d->engine());
+ d->setProperty(arrayIndex, QScriptValuePrivate::get(value), QScriptConverter::toPropertyAttributes(flags));
}
/*!
- 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
-{
- Q_D(const QScriptValue);
- if (!d)
- return 0;
- return QScriptEnginePrivate::get(d->engine);
-}
+ 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.
-/*!
- \obsolete
+ 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.
- Use isBool() instead.
+ \sa QScriptEngine::toStringHandle()
*/
-bool QScriptValue::isBoolean() const
+void QScriptValue::setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags)
{
- Q_D(const QScriptValue);
- return d && d->isJSC() && d->jscValue.isBoolean();
+ Q_D(QScriptValue);
+ QScriptIsolate api(d->engine());
+ d->setProperty(QScriptStringPrivate::get(name), QScriptValuePrivate::get(value), QScriptConverter::toPropertyAttributes(flags));
}
/*!
- \since 4.5
-
- Returns true if this QScriptValue is of the primitive type Boolean;
- otherwise returns false.
+ Returns the flags of the property with the given \a name, using the
+ given \a mode to resolve the property.
- \sa toBool()
+ \sa property()
*/
-bool QScriptValue::isBool() const
+QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString& name, const ResolveFlags& mode) const
{
Q_D(const QScriptValue);
- return d && d->isJSC() && d->jscValue.isBoolean();
+ QScriptIsolate api(d->engine());
+ return d->propertyFlags(name, mode);
}
/*!
- Returns true if this QScriptValue is of the primitive type Number;
- otherwise returns false.
+ Returns the flags of the property with the given \a name, using the
+ given \a mode to resolve the property.
- \sa toNumber()
+ \sa property()
*/
-bool QScriptValue::isNumber() const
+QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString& name, const ResolveFlags& mode) const
{
Q_D(const QScriptValue);
- if (!d)
- return false;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore:
- return d->jscValue.isNumber();
- case QScriptValuePrivate::Number:
- return true;
- case QScriptValuePrivate::String:
- return false;
- }
- return false;
+ QScriptIsolate api(d->engine());
+ return d->propertyFlags(QScriptStringPrivate::get(name), mode);
}
/*!
- Returns true if this QScriptValue is of the primitive type String;
- otherwise returns false.
-
- \sa toString()
-*/
-bool QScriptValue::isString() const
+ * If this QScriptValue is a QObject, returns the QObject pointer
+ * that the QScriptValue represents; otherwise, returns 0.
+ *
+ * If the QObject that this QScriptValue wraps has been deleted,
+ * this function returns 0 (i.e. it is possible for toQObject()
+ * to return 0 even when isQObject() returns true).
+ *
+ * \sa isQObject()
+ */
+QObject *QScriptValue::toQObject() const
{
Q_D(const QScriptValue);
- if (!d)
- return false;
- switch (d->type) {
- case QScriptValuePrivate::JavaScriptCore:
- return d->jscValue.isString();
- case QScriptValuePrivate::Number:
- return false;
- case QScriptValuePrivate::String:
- return true;
- }
- return false;
+ QScriptIsolate api(d->engine());
+ QScriptDeclarativeClass *cls = QScriptDeclarativeClassObject::declarativeClass(d);
+ if (cls)
+ return cls->toQObject(QScriptDeclarativeClassObject::object(d));
+ return d->toQObject();
}
/*!
- Returns true if this QScriptValue is a function; otherwise returns
- false.
+ If this QScriptValue is a QMetaObject, returns the QMetaObject pointer
+ that the QScriptValue represents; otherwise, returns 0.
- \sa call()
+ \sa isQMetaObject()
*/
-bool QScriptValue::isFunction() const
+const QMetaObject *QScriptValue::toQMetaObject() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScript::isFunction(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->toQMetaObject();
}
/*!
- Returns true if this QScriptValue is of the primitive type Null;
- otherwise returns false.
+ 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 QScriptEngine::nullValue()
+ \sa isDate()
*/
-bool QScriptValue::isNull() const
+QDateTime QScriptValue::toDateTime() const
{
Q_D(const QScriptValue);
- return d && d->isJSC() && d->jscValue.isNull();
+ QScriptIsolate api(d->engine());
+ return d->toDataTime();
}
/*!
- Returns true if this QScriptValue is of the primitive type Undefined;
- otherwise returns false.
+ Returns the QRegExp representation of this value.
+ If this QScriptValue is not a regular expression, an empty
+ QRegExp is returned.
- \sa QScriptEngine::undefinedValue()
+ \sa isRegExp()
*/
-bool QScriptValue::isUndefined() const
+QRegExp QScriptValue::toRegExp() const
{
Q_D(const QScriptValue);
- return d && d->isJSC() && d->jscValue.isUndefined();
+ QScriptIsolate api(d->engine());
+ return d->toRegExp();
}
/*!
- 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.
+ Returns true if this QScriptValue is an object of the Date class;
+ otherwise returns false.
- \sa toObject(), QScriptEngine::newObject()
+ \sa QScriptEngine::newDate()
*/
-bool QScriptValue::isObject() const
+bool QScriptValue::isDate() const
{
Q_D(const QScriptValue);
- return d && d->isObject();
+ QScriptIsolate api(d->engine());
+ return d->isDate();
}
/*!
- Returns true if this QScriptValue is a variant value;
+ Returns true if this QScriptValue is an object of the RegExp class;
otherwise returns false.
- \sa toVariant(), QScriptEngine::newVariant()
+ \sa QScriptEngine::newRegExp()
*/
-bool QScriptValue::isVariant() const
+bool QScriptValue::isRegExp() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isVariant(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->isRegExp();
}
/*!
@@ -1982,9 +1159,11 @@ bool QScriptValue::isVariant() const
bool QScriptValue::isQObject() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isQObject(d->jscValue);
+ QScriptIsolate api(d->engine());
+ QScriptDeclarativeClass *cls = QScriptDeclarativeClassObject::declarativeClass(d);
+ if (cls)
+ return cls->isQObject();
+ return d->isQObject();
}
/*!
@@ -1996,19 +1175,27 @@ bool QScriptValue::isQObject() const
bool QScriptValue::isQMetaObject() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC())
- return false;
- return QScriptEnginePrivate::isQMetaObject(d->jscValue);
+ QScriptIsolate api(d->engine());
+ return d->isQMetaObject();
}
/*!
- Returns true if this QScriptValue is valid; otherwise returns
- false.
+ \internal
*/
-bool QScriptValue::isValid() const
+QScriptValue QScriptValue::scope() const
{
- Q_D(const QScriptValue);
- return d && (!d->isJSC() || !!d->jscValue);
+ // FIXME can it be removed?
+ Q_UNIMPLEMENTED();
+ return QScriptValue();
+}
+
+/*!
+ \internal
+*/
+void QScriptValue::setScope(const QScriptValue &)
+{
+ // FIXME can it be removed?
+ Q_UNIMPLEMENTED();
}
/*!
@@ -2022,15 +1209,8 @@ bool QScriptValue::isValid() const
QScriptValue QScriptValue::data() const
{
Q_D(const QScriptValue);
- if (!d || !d->isObject())
- return QScriptValue();
- if (d->jscValue.inherits(&QScriptObject::info)) {
- QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
- return d->engine->scriptValueFromJSCValue(scriptObject->data());
- } else {
- // ### make hidden property
- return property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal);
- }
+ QScriptIsolate api(d->engine());
+ return QScriptValuePrivate::get(d->data());
}
/*!
@@ -2043,26 +1223,11 @@ QScriptValue QScriptValue::data() const
\sa QScriptEngine::reportAdditionalMemoryCost()
*/
-void QScriptValue::setData(const QScriptValue &data)
+void QScriptValue::setData(const QScriptValue &value)
{
- Q_D(QScriptValue);
- if (!d || !d->isObject())
- return;
- QScript::APIShim shim(d->engine);
- JSC::JSValue other = d->engine->scriptValueToJSCValue(data);
- if (d->jscValue.inherits(&QScriptObject::info)) {
- QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
- scriptObject->setData(other);
- } else {
- JSC::ExecState *exec = d->engine->currentFrame;
- JSC::Identifier id = JSC::Identifier(exec, "__qt_data__");
- if (!data.isValid()) {
- JSC::asObject(d->jscValue)->removeDirect(id);
- } else {
- // ### make hidden property
- JSC::asObject(d->jscValue)->putDirect(id, other);
- }
- }
+ Q_D(const QScriptValue);
+ QScriptIsolate api(d->engine());
+ d->setData(QScriptValuePrivate::get(value));
}
/*!
@@ -2076,13 +1241,8 @@ void QScriptValue::setData(const QScriptValue &data)
QScriptClass *QScriptValue::scriptClass() const
{
Q_D(const QScriptValue);
- if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
- return 0;
- QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
- QScriptObjectDelegate *delegate = scriptObject->delegate();
- if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject))
- return 0;
- return static_cast<QScript::ClassObjectDelegate*>(delegate)->scriptClass();
+ QScriptIsolate api(d->engine());
+ return QScriptClassPrivate::safeGet(d->scriptClass());
}
/*!
@@ -2098,29 +1258,59 @@ QScriptClass *QScriptValue::scriptClass() const
\sa scriptClass(), setData()
*/
-void QScriptValue::setScriptClass(QScriptClass *scriptClass)
+void QScriptValue::setScriptClass(QScriptClass *scriptclass)
{
Q_D(QScriptValue);
- if (!d || !d->isObject())
- return;
- if (!d->jscValue.inherits(&QScriptObject::info)) {
- qWarning("QScriptValue::setScriptClass() failed: "
- "cannot change class of non-QScriptObject");
+ QScriptIsolate api(d->engine());
+ d->setScriptClass(QScriptClassPrivate::safeGet(scriptclass));
+}
+
+/*!
+ \internal
+ Get script class if it exists
+ \note it can be null
+*/
+QScriptClassPrivate* QScriptValuePrivate::scriptClass() const
+{
+ QScriptClassObject *data = QScriptClassObject::safeGet(this);
+ if (data)
+ return data->scriptClass();
+ return 0;
+}
+
+void QScriptValuePrivate::setScriptClass(QScriptClassPrivate *scriptclass)
+{
+ if (!isObject())
return;
- }
- QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
- if (!scriptClass) {
- scriptObject->setDelegate(0);
- } else {
- QScriptObjectDelegate *delegate = scriptObject->delegate();
- if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) {
- delegate = new QScript::ClassObjectDelegate(scriptClass);
- scriptObject->setDelegate(delegate);
+
+ v8::HandleScope scope;
+ // FIXME this algorithm is bad. It creates new value instead to add functionality to exiting one
+ // This code would fail
+ // engine.evaluate("a = new Object()");
+ // QSV obj1 = engine.evaluate("a");
+ // QSV obj2 = engine.evaluate("a");
+ // obj1.setScriptClass(scriptclass);
+ // QVERIFY(obj1.strictlyEquals(obj2);
+
+ QScriptClassObject *data = QScriptClassObject::safeGet(this);
+ if (data) {
+ data->setScriptClass(scriptclass);
+ if (!scriptclass) {
+ if (data->original().IsEmpty())
+ data->setOriginal(v8::Object::New());
+ reinitialize(engine(), data->original());
}
- static_cast<QScript::ClassObjectDelegate*>(delegate)->setScriptClass(scriptClass);
+ return;
}
+ if (!scriptclass)
+ return;
+
+ v8::Handle<v8::Object> self = v8::Handle<v8::Object>::Cast(m_value);
+ v8::Handle<v8::Value> newObject = QScriptClassObject::newInstance(scriptclass, self, engine());
+ reinitialize(engine(), newObject);
}
+
/*!
\internal
@@ -2131,6 +1321,8 @@ void QScriptValue::setScriptClass(QScriptClass *scriptClass)
*/
qint64 QScriptValue::objectId() const
{
- return d_ptr?d_ptr->objectId():-1;
+ Q_D(const QScriptValue);
+ return d->objectId();
}
+
QT_END_NAMESPACE