0
+ − 1
/****************************************************************************
+ − 2
**
+ − 3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ − 4
** All rights reserved.
+ − 5
** Contact: Nokia Corporation (qt-info@nokia.com)
+ − 6
**
+ − 7
** This file is part of the QtScript module of the Qt Toolkit.
+ − 8
**
+ − 9
** $QT_BEGIN_LICENSE:LGPL$
+ − 10
** No Commercial Usage
+ − 11
** This file contains pre-release code and may not be distributed.
+ − 12
** You may use this file in accordance with the terms and conditions
+ − 13
** contained in the Technology Preview License Agreement accompanying
+ − 14
** this package.
+ − 15
**
+ − 16
** GNU Lesser General Public License Usage
+ − 17
** Alternatively, this file may be used under the terms of the GNU Lesser
+ − 18
** General Public License version 2.1 as published by the Free Software
+ − 19
** Foundation and appearing in the file LICENSE.LGPL included in the
+ − 20
** packaging of this file. Please review the following information to
+ − 21
** ensure the GNU Lesser General Public License version 2.1 requirements
+ − 22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ − 23
**
+ − 24
** In addition, as a special exception, Nokia gives you certain additional
+ − 25
** rights. These rights are described in the Nokia Qt LGPL Exception
+ − 26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ − 27
**
+ − 28
** If you have questions regarding the use of this file, please contact
+ − 29
** Nokia at qt-info@nokia.com.
+ − 30
**
+ − 31
**
+ − 32
**
+ − 33
**
+ − 34
**
+ − 35
**
+ − 36
**
+ − 37
**
+ − 38
** $QT_END_LICENSE$
+ − 39
**
+ − 40
****************************************************************************/
+ − 41
+ − 42
#include "config.h"
+ − 43
#include "qscriptvalue.h"
+ − 44
+ − 45
#include "qscriptvalue_p.h"
+ − 46
#include "qscriptengine.h"
+ − 47
#include "qscriptengine_p.h"
+ − 48
#include "qscriptstring_p.h"
+ − 49
+ − 50
#include "JSArray.h"
+ − 51
#include "JSGlobalObject.h"
+ − 52
#include "JSImmediate.h"
+ − 53
#include "JSObject.h"
+ − 54
#include "JSValue.h"
+ − 55
#include "JSFunction.h"
+ − 56
#include "DateInstance.h"
+ − 57
#include "ErrorInstance.h"
+ − 58
#include "RegExpObject.h"
+ − 59
#include "Identifier.h"
+ − 60
#include "Operations.h"
+ − 61
#include "Arguments.h"
+ − 62
+ − 63
#include <QtCore/qdatetime.h>
+ − 64
#include <QtCore/qregexp.h>
+ − 65
#include <QtCore/qvariant.h>
+ − 66
#include <QtCore/qvarlengtharray.h>
+ − 67
#include <QtCore/qnumeric.h>
+ − 68
+ − 69
#include "utils/qscriptdate_p.h"
+ − 70
#include "bridge/qscriptobject_p.h"
+ − 71
#include "bridge/qscriptclassobject_p.h"
+ − 72
#include "bridge/qscriptvariant_p.h"
+ − 73
#include "bridge/qscriptqobject_p.h"
+ − 74
+ − 75
/*!
+ − 76
\since 4.3
+ − 77
\class QScriptValue
+ − 78
+ − 79
\brief The QScriptValue class acts as a container for the Qt Script data types.
+ − 80
+ − 81
\ingroup script
+ − 82
\mainclass
+ − 83
+ − 84
QScriptValue supports the types defined in the \l{ECMA-262}
+ − 85
standard: The primitive types, which are Undefined, Null, Boolean,
+ − 86
Number, and String; and the Object type. Additionally, Qt Script
+ − 87
has built-in support for QVariant, QObject and QMetaObject.
+ − 88
+ − 89
For the object-based types (including Date and RegExp), use the
+ − 90
newT() functions in QScriptEngine (e.g. QScriptEngine::newObject())
+ − 91
to create a QScriptValue of the desired type. For the primitive types,
+ − 92
use one of the QScriptValue constructor overloads.
+ − 93
+ − 94
The methods named isT() (e.g. isBool(), isUndefined()) can be
+ − 95
used to test if a value is of a certain type. The methods named
+ − 96
toT() (e.g. toBool(), toString()) can be used to convert a
+ − 97
QScriptValue to another type. You can also use the generic
+ − 98
qscriptvalue_cast() function.
+ − 99
+ − 100
Object values have zero or more properties which are themselves
+ − 101
QScriptValues. Use setProperty() to set a property of an object, and
+ − 102
call property() to retrieve the value of a property.
+ − 103
+ − 104
\snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 0
+ − 105
+ − 106
Each property can have a set of attributes; these are specified as
+ − 107
the third (optional) argument to setProperty(). The attributes of a
+ − 108
property can be queried by calling the propertyFlags() function. The
+ − 109
following code snippet creates a property that cannot be modified by
+ − 110
script code:
+ − 111
+ − 112
\snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 1
+ − 113
+ − 114
If you want to iterate over the properties of a script object, use
+ − 115
the QScriptValueIterator class.
+ − 116
+ − 117
Object values have an internal \c{prototype} property, which can be
+ − 118
accessed with prototype() and setPrototype(). Properties added to a
+ − 119
prototype are shared by all objects having that prototype; this is
+ − 120
referred to as prototype-based inheritance. In practice, it means
+ − 121
that (by default) the property() function will automatically attempt
+ − 122
to look up look the property in the prototype() (and in the
+ − 123
prototype of the prototype(), and so on), if the object itself does
+ − 124
not have the requested property. Note that this prototype-based
+ − 125
lookup is not performed by setProperty(); setProperty() will always
+ − 126
create the property in the script object itself. For more
+ − 127
information, see the \l{QtScript} documentation.
+ − 128
+ − 129
Function objects (objects for which isFunction() returns true) can
+ − 130
be invoked by calling call(). Constructor functions can be used to
+ − 131
construct new objects by calling construct().
+ − 132
+ − 133
Use equals(), strictlyEquals() and lessThan() to compare a QScriptValue
+ − 134
to another.
+ − 135
+ − 136
Object values can have custom data associated with them; see the
+ − 137
setData() and data() functions. By default, this data is not
+ − 138
accessible to scripts; it can be used to store any data you want to
+ − 139
associate with the script object. Typically this is used by custom
+ − 140
class objects (see QScriptClass) to store a C++ type that contains
+ − 141
the "native" object data.
+ − 142
+ − 143
Note that a QScriptValue for which isObject() is true only carries a
+ − 144
reference to an actual object; copying the QScriptValue will only
+ − 145
copy the object reference, not the object itself. If you want to
+ − 146
clone an object (i.e. copy an object's properties to another
+ − 147
object), you can do so with the help of a \c{for-in} statement in
+ − 148
script code, or QScriptValueIterator in C++.
+ − 149
+ − 150
\sa QScriptEngine, QScriptValueIterator
+ − 151
*/
+ − 152
+ − 153
/*!
+ − 154
\enum QScriptValue::SpecialValue
+ − 155
+ − 156
This enum is used to specify a single-valued type.
+ − 157
+ − 158
\value UndefinedValue An undefined value.
+ − 159
+ − 160
\value NullValue A null value.
+ − 161
*/
+ − 162
+ − 163
/*!
+ − 164
\enum QScriptValue::PropertyFlag
+ − 165
+ − 166
This enum describes the attributes of a property.
+ − 167
+ − 168
\value ReadOnly The property is read-only. Attempts by Qt Script code to write to the property will be ignored.
+ − 169
+ − 170
\value Undeletable Attempts by Qt Script code to \c{delete} the property will be ignored.
+ − 171
+ − 172
\value SkipInEnumeration The property is not to be enumerated by a \c{for-in} enumeration.
+ − 173
+ − 174
\value PropertyGetter The property is defined by a function which will be called to get the property value.
+ − 175
+ − 176
\value PropertySetter The property is defined by a function which will be called to set the property value.
+ − 177
+ − 178
\value QObjectMember This flag is used to indicate that an existing property is a QObject member (a property or method).
+ − 179
+ − 180
\value KeepExistingFlags This value is used to indicate to setProperty() that the property's flags should be left unchanged. If the property doesn't exist, the default flags (0) will be used.
+ − 181
+ − 182
\value UserRange Flags in this range are not used by Qt Script, and can be used for custom purposes.
+ − 183
*/
+ − 184
+ − 185
/*!
+ − 186
\enum QScriptValue::ResolveFlag
+ − 187
+ − 188
This enum specifies how to look up a property of an object.
+ − 189
+ − 190
\value ResolveLocal Only check the object's own properties.
+ − 191
+ − 192
\value ResolvePrototype Check the object's own properties first, then search the prototype chain. This is the default.
+ − 193
+ − 194
\omitvalue ResolveScope Check the object's own properties first, then search the scope chain.
+ − 195
+ − 196
\omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain.
+ − 197
*/
+ − 198
+ − 199
// ### move
+ − 200
+ − 201
#include <QtCore/qnumeric.h>
+ − 202
#include <math.h>
+ − 203
+ − 204
QT_BEGIN_NAMESPACE
+ − 205
+ − 206
namespace QScript
+ − 207
{
+ − 208
+ − 209
static const qsreal D32 = 4294967296.0;
+ − 210
+ − 211
qint32 ToInt32(qsreal n)
+ − 212
{
+ − 213
if (qIsNaN(n) || qIsInf(n) || (n == 0))
+ − 214
return 0;
+ − 215
+ − 216
qsreal sign = (n < 0) ? -1.0 : 1.0;
+ − 217
qsreal abs_n = fabs(n);
+ − 218
+ − 219
n = ::fmod(sign * ::floor(abs_n), D32);
+ − 220
const double D31 = D32 / 2.0;
+ − 221
+ − 222
if (sign == -1 && n < -D31)
+ − 223
n += D32;
+ − 224
+ − 225
else if (sign != -1 && n >= D31)
+ − 226
n -= D32;
+ − 227
+ − 228
return qint32 (n);
+ − 229
}
+ − 230
+ − 231
quint32 ToUint32(qsreal n)
+ − 232
{
+ − 233
if (qIsNaN(n) || qIsInf(n) || (n == 0))
+ − 234
return 0;
+ − 235
+ − 236
qsreal sign = (n < 0) ? -1.0 : 1.0;
+ − 237
qsreal abs_n = fabs(n);
+ − 238
+ − 239
n = ::fmod(sign * ::floor(abs_n), D32);
+ − 240
+ − 241
if (n < 0)
+ − 242
n += D32;
+ − 243
+ − 244
return quint32 (n);
+ − 245
}
+ − 246
+ − 247
quint16 ToUint16(qsreal n)
+ − 248
{
+ − 249
static const qsreal D16 = 65536.0;
+ − 250
+ − 251
if (qIsNaN(n) || qIsInf(n) || (n == 0))
+ − 252
return 0;
+ − 253
+ − 254
qsreal sign = (n < 0) ? -1.0 : 1.0;
+ − 255
qsreal abs_n = fabs(n);
+ − 256
+ − 257
n = ::fmod(sign * ::floor(abs_n), D16);
+ − 258
+ − 259
if (n < 0)
+ − 260
n += D16;
+ − 261
+ − 262
return quint16 (n);
+ − 263
}
+ − 264
+ − 265
qsreal ToInteger(qsreal n)
+ − 266
{
+ − 267
if (qIsNaN(n))
+ − 268
return 0;
+ − 269
+ − 270
if (n == 0 || qIsInf(n))
+ − 271
return n;
+ − 272
+ − 273
int sign = n < 0 ? -1 : 1;
+ − 274
return sign * ::floor(::fabs(n));
+ − 275
}
+ − 276
+ − 277
} // namespace QScript
+ − 278
+ − 279
QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const
+ − 280
{
+ − 281
JSC::JSValue result;
+ − 282
if (!(resolveMode & QScriptValue::ResolvePrototype)) {
+ − 283
// Look in the object's own properties
+ − 284
JSC::ExecState *exec = engine->currentFrame;
+ − 285
JSC::JSObject *object = JSC::asObject(jscValue);
+ − 286
JSC::PropertySlot slot(object);
+ − 287
if (object->getOwnPropertySlot(exec, id, slot))
+ − 288
result = slot.getValue(exec, id);
+ − 289
}
+ − 290
if (!result && (resolveMode & QScriptValue::ResolveScope)) {
+ − 291
// ### check if it's a function object and look in the scope chain
+ − 292
QScriptValue scope = property(QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal);
+ − 293
if (scope.isObject())
+ − 294
result = engine->scriptValueToJSCValue(QScriptValuePrivate::get(scope)->property(id, resolveMode));
+ − 295
}
+ − 296
return engine->scriptValueFromJSCValue(result);
+ − 297
}
+ − 298
+ − 299
QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const
+ − 300
{
+ − 301
JSC::JSValue result;
+ − 302
if (!(resolveMode & QScriptValue::ResolvePrototype)) {
+ − 303
// Look in the object's own properties
+ − 304
JSC::ExecState *exec = engine->currentFrame;
+ − 305
JSC::JSObject *object = JSC::asObject(jscValue);
+ − 306
JSC::PropertySlot slot(object);
+ − 307
if (object->getOwnPropertySlot(exec, index, slot))
+ − 308
result = slot.getValue(exec, index);
+ − 309
}
+ − 310
return engine->scriptValueFromJSCValue(result);
+ − 311
}
+ − 312
+ − 313
void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value,
+ − 314
const QScriptValue::PropertyFlags &flags)
+ − 315
{
+ − 316
QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value);
+ − 317
if (valueEngine && (valueEngine != engine)) {
+ − 318
qWarning("QScriptValue::setProperty(%s) failed: "
+ − 319
"cannot set value created in a different engine",
+ − 320
qPrintable(QString(id.ustring())));
+ − 321
return;
+ − 322
}
+ − 323
JSC::ExecState *exec = engine->currentFrame;
+ − 324
JSC::JSValue jsValue = engine->scriptValueToJSCValue(value);
+ − 325
JSC::JSObject *thisObject = JSC::asObject(jscValue);
+ − 326
JSC::JSValue setter = thisObject->lookupSetter(exec, id);
+ − 327
JSC::JSValue getter = thisObject->lookupGetter(exec, id);
+ − 328
if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
+ − 329
if (!jsValue) {
+ − 330
// deleting getter/setter
+ − 331
if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) {
+ − 332
// deleting both: just delete the property
+ − 333
thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ − 334
} else if (flags & QScriptValue::PropertyGetter) {
+ − 335
// preserve setter, if there is one
+ − 336
thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ − 337
if (setter && setter.isObject())
+ − 338
thisObject->defineSetter(exec, id, JSC::asObject(setter));
+ − 339
} else { // flags & QScriptValue::PropertySetter
+ − 340
// preserve getter, if there is one
+ − 341
thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ − 342
if (getter && getter.isObject())
+ − 343
thisObject->defineGetter(exec, id, JSC::asObject(getter));
+ − 344
}
+ − 345
} else {
+ − 346
if (jsValue.isObject()) { // ### should check if it has callData()
+ − 347
// defining getter/setter
+ − 348
if (id == exec->propertyNames().underscoreProto) {
+ − 349
qWarning("QScriptValue::setProperty() failed: "
+ − 350
"cannot set getter or setter of native property `__proto__'");
+ − 351
} else {
+ − 352
if (flags & QScriptValue::PropertyGetter)
+ − 353
thisObject->defineGetter(exec, id, JSC::asObject(jsValue));
+ − 354
if (flags & QScriptValue::PropertySetter)
+ − 355
thisObject->defineSetter(exec, id, JSC::asObject(jsValue));
+ − 356
}
+ − 357
} else {
+ − 358
qWarning("QScriptValue::setProperty(): getter/setter must be a function");
+ − 359
}
+ − 360
}
+ − 361
} else {
+ − 362
// setting the value
+ − 363
if (getter && getter.isObject() && !(setter && setter.isObject())) {
+ − 364
qWarning("QScriptValue::setProperty() failed: "
+ − 365
"property '%s' has a getter but no setter",
+ − 366
qPrintable(QString(id.ustring())));
+ − 367
return;
+ − 368
}
+ − 369
if (!jsValue) {
+ − 370
// ### check if it's a getter/setter property
+ − 371
thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false);
+ − 372
} else if (flags != QScriptValue::KeepExistingFlags) {
+ − 373
if (thisObject->hasOwnProperty(exec, id))
+ − 374
thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes?
+ − 375
unsigned attribs = 0;
+ − 376
if (flags & QScriptValue::ReadOnly)
+ − 377
attribs |= JSC::ReadOnly;
+ − 378
if (flags & QScriptValue::SkipInEnumeration)
+ − 379
attribs |= JSC::DontEnum;
+ − 380
if (flags & QScriptValue::Undeletable)
+ − 381
attribs |= JSC::DontDelete;
+ − 382
attribs |= flags & QScriptValue::UserRange;
+ − 383
thisObject->putWithAttributes(exec, id, jsValue, attribs);
+ − 384
} else {
+ − 385
JSC::PutPropertySlot slot;
+ − 386
thisObject->put(exec, id, jsValue, slot);
+ − 387
}
+ − 388
}
+ − 389
}
+ − 390
+ − 391
QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id,
+ − 392
const QScriptValue::ResolveFlags &mode) const
+ − 393
{
+ − 394
JSC::ExecState *exec = engine->currentFrame;
+ − 395
JSC::JSObject *object = JSC::asObject(jscValue);
+ − 396
unsigned attribs = 0;
+ − 397
JSC::PropertyDescriptor descriptor;
+ − 398
if (object->getOwnPropertyDescriptor(exec, id, descriptor))
+ − 399
attribs = descriptor.attributes();
+ − 400
else if (!object->getPropertyAttributes(exec, id, attribs)) {
+ − 401
if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
+ − 402
QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype());
+ − 403
return QScriptValuePrivate::get(proto)->propertyFlags(id, mode);
+ − 404
}
+ − 405
return 0;
+ − 406
}
+ − 407
QScriptValue::PropertyFlags result = 0;
+ − 408
if (attribs & JSC::ReadOnly)
+ − 409
result |= QScriptValue::ReadOnly;
+ − 410
if (attribs & JSC::DontEnum)
+ − 411
result |= QScriptValue::SkipInEnumeration;
+ − 412
if (attribs & JSC::DontDelete)
+ − 413
result |= QScriptValue::Undeletable;
+ − 414
//We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
+ − 415
if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
+ − 416
result |= QScriptValue::PropertyGetter;
+ − 417
if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
+ − 418
result |= QScriptValue::PropertySetter;
+ − 419
if (attribs & QScript::QObjectMemberAttribute)
+ − 420
result |= QScriptValue::QObjectMember;
+ − 421
result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
+ − 422
return result;
+ − 423
}
+ − 424
+ − 425
QVariant &QScriptValuePrivate::variantValue() const
+ − 426
{
+ − 427
Q_ASSERT(jscValue.inherits(&QScriptObject::info));
+ − 428
QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate();
+ − 429
Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
+ − 430
return static_cast<QScript::QVariantDelegate*>(delegate)->value();
+ − 431
}
+ − 432
+ − 433
void QScriptValuePrivate::setVariantValue(const QVariant &value)
+ − 434
{
+ − 435
Q_ASSERT(jscValue.inherits(&QScriptObject::info));
+ − 436
QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate();
+ − 437
Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant));
+ − 438
static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value);
+ − 439
}
+ − 440
+ − 441
void QScriptValuePrivate::detachFromEngine()
+ − 442
{
+ − 443
if (isJSC())
+ − 444
jscValue = JSC::JSValue();
+ − 445
engine = 0;
+ − 446
}
+ − 447
+ − 448
/*!
+ − 449
\internal
+ − 450
*/
+ − 451
QScriptValue::QScriptValue(QScriptValuePrivate *d)
+ − 452
: d_ptr(d)
+ − 453
{
+ − 454
}
+ − 455
+ − 456
/*!
+ − 457
Constructs an invalid QScriptValue.
+ − 458
*/
+ − 459
QScriptValue::QScriptValue()
+ − 460
: d_ptr(0)
+ − 461
{
+ − 462
}
+ − 463
+ − 464
/*!
+ − 465
Destroys this QScriptValue.
+ − 466
*/
+ − 467
QScriptValue::~QScriptValue()
+ − 468
{
+ − 469
}
+ − 470
+ − 471
/*!
+ − 472
Constructs a new QScriptValue that is a copy of \a other.
+ − 473
+ − 474
Note that if \a other is an object (i.e., isObject() would return
+ − 475
true), then only a reference to the underlying object is copied into
+ − 476
the new script value (i.e., the object itself is not copied).
+ − 477
*/
+ − 478
QScriptValue::QScriptValue(const QScriptValue &other)
+ − 479
: d_ptr(other.d_ptr)
+ − 480
{
+ − 481
}
+ − 482
+ − 483
/*!
+ − 484
\obsolete
+ − 485
+ − 486
Constructs a new QScriptValue with the special \a value and
+ − 487
registers it with the script \a engine.
+ − 488
*/
+ − 489
QScriptValue::QScriptValue(QScriptEngine *engine, QScriptValue::SpecialValue value)
+ − 490
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 491
{
+ − 492
switch (value) {
+ − 493
case NullValue:
+ − 494
d_ptr->initFrom(JSC::jsNull());
+ − 495
break;
+ − 496
case UndefinedValue:
+ − 497
d_ptr->initFrom(JSC::jsUndefined());
+ − 498
break;
+ − 499
}
+ − 500
}
+ − 501
+ − 502
/*!
+ − 503
\obsolete
+ − 504
+ − 505
\fn QScriptValue::QScriptValue(QScriptEngine *engine, bool value)
+ − 506
+ − 507
Constructs a new QScriptValue with the boolean \a value and
+ − 508
registers it with the script \a engine.
+ − 509
*/
+ − 510
QScriptValue::QScriptValue(QScriptEngine *engine, bool val)
+ − 511
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 512
{
+ − 513
d_ptr->initFrom(JSC::jsBoolean(val));
+ − 514
}
+ − 515
+ − 516
/*!
+ − 517
\fn QScriptValue::QScriptValue(QScriptEngine *engine, int value)
+ − 518
\obsolete
+ − 519
+ − 520
Constructs a new QScriptValue with the integer \a value and
+ − 521
registers it with the script \a engine.
+ − 522
*/
+ − 523
QScriptValue::QScriptValue(QScriptEngine *engine, int val)
+ − 524
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 525
{
+ − 526
if (engine) {
+ − 527
JSC::ExecState *exec = d_ptr->engine->currentFrame;
+ − 528
d_ptr->initFrom(JSC::jsNumber(exec, val));
+ − 529
} else
+ − 530
d_ptr->initFrom(val);
+ − 531
}
+ − 532
+ − 533
/*!
+ − 534
\fn QScriptValue::QScriptValue(QScriptEngine *engine, uint value)
+ − 535
\obsolete
+ − 536
+ − 537
Constructs a new QScriptValue with the unsigned integer \a value and
+ − 538
registers it with the script \a engine.
+ − 539
*/
+ − 540
QScriptValue::QScriptValue(QScriptEngine *engine, uint val)
+ − 541
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 542
{
+ − 543
if (engine) {
+ − 544
JSC::ExecState *exec = d_ptr->engine->currentFrame;
+ − 545
d_ptr->initFrom(JSC::jsNumber(exec, val));
+ − 546
} else
+ − 547
d_ptr->initFrom(val);
+ − 548
}
+ − 549
+ − 550
/*!
+ − 551
\fn QScriptValue::QScriptValue(QScriptEngine *engine, qsreal value)
+ − 552
\obsolete
+ − 553
+ − 554
Constructs a new QScriptValue with the qsreal \a value and
+ − 555
registers it with the script \a engine.
+ − 556
*/
+ − 557
QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val)
+ − 558
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 559
{
+ − 560
if (engine) {
+ − 561
JSC::ExecState *exec = d_ptr->engine->currentFrame;
+ − 562
d_ptr->initFrom(JSC::jsNumber(exec, val));
+ − 563
} else
+ − 564
d_ptr->initFrom(val);
+ − 565
}
+ − 566
+ − 567
/*!
+ − 568
\fn QScriptValue::QScriptValue(QScriptEngine *engine, const QString &value)
+ − 569
\obsolete
+ − 570
+ − 571
Constructs a new QScriptValue with the string \a value and
+ − 572
registers it with the script \a engine.
+ − 573
*/
+ − 574
QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val)
+ − 575
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 576
{
+ − 577
if (engine) {
+ − 578
JSC::ExecState *exec = d_ptr->engine->currentFrame;
+ − 579
d_ptr->initFrom(JSC::jsString(exec, val));
+ − 580
} else {
+ − 581
d_ptr->initFrom(val);
+ − 582
}
+ − 583
}
+ − 584
+ − 585
/*!
+ − 586
\fn QScriptValue::QScriptValue(QScriptEngine *engine, const char *value)
+ − 587
\obsolete
+ − 588
+ − 589
Constructs a new QScriptValue with the string \a value and
+ − 590
registers it with the script \a engine.
+ − 591
*/
+ − 592
+ − 593
#ifndef QT_NO_CAST_FROM_ASCII
+ − 594
QScriptValue::QScriptValue(QScriptEngine *engine, const char *val)
+ − 595
: d_ptr(new (QScriptEnginePrivate::get(engine))QScriptValuePrivate(QScriptEnginePrivate::get(engine)))
+ − 596
{
+ − 597
if (engine) {
+ − 598
JSC::ExecState *exec = d_ptr->engine->currentFrame;
+ − 599
d_ptr->initFrom(JSC::jsString(exec, val));
+ − 600
} else {
+ − 601
d_ptr->initFrom(QString::fromAscii(val));
+ − 602
}
+ − 603
}
+ − 604
#endif
+ − 605
+ − 606
/*!
+ − 607
\since 4.5
+ − 608
+ − 609
Constructs a new QScriptValue with a special \a value.
+ − 610
*/
+ − 611
QScriptValue::QScriptValue(SpecialValue value)
+ − 612
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 613
{
+ − 614
switch (value) {
+ − 615
case NullValue:
+ − 616
d_ptr->initFrom(JSC::jsNull());
+ − 617
break;
+ − 618
case UndefinedValue:
+ − 619
d_ptr->initFrom(JSC::jsUndefined());
+ − 620
break;
+ − 621
}
+ − 622
}
+ − 623
+ − 624
/*!
+ − 625
\since 4.5
+ − 626
+ − 627
Constructs a new QScriptValue with a boolean \a value.
+ − 628
*/
+ − 629
QScriptValue::QScriptValue(bool value)
+ − 630
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 631
{
+ − 632
d_ptr->initFrom(JSC::jsBoolean(value));
+ − 633
}
+ − 634
+ − 635
/*!
+ − 636
\since 4.5
+ − 637
+ − 638
Constructs a new QScriptValue with a number \a value.
+ − 639
*/
+ − 640
QScriptValue::QScriptValue(int value)
+ − 641
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 642
{
+ − 643
d_ptr->initFrom(value);
+ − 644
}
+ − 645
+ − 646
/*!
+ − 647
\since 4.5
+ − 648
+ − 649
Constructs a new QScriptValue with a number \a value.
+ − 650
*/
+ − 651
QScriptValue::QScriptValue(uint value)
+ − 652
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 653
{
+ − 654
d_ptr->initFrom(value);
+ − 655
}
+ − 656
+ − 657
/*!
+ − 658
\since 4.5
+ − 659
+ − 660
Constructs a new QScriptValue with a number \a value.
+ − 661
*/
+ − 662
QScriptValue::QScriptValue(qsreal value)
+ − 663
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 664
{
+ − 665
d_ptr->initFrom(value);
+ − 666
}
+ − 667
+ − 668
/*!
+ − 669
\since 4.5
+ − 670
+ − 671
Constructs a new QScriptValue with a string \a value.
+ − 672
*/
+ − 673
QScriptValue::QScriptValue(const QString &value)
+ − 674
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 675
{
+ − 676
d_ptr->initFrom(value);
+ − 677
}
+ − 678
+ − 679
/*!
+ − 680
\since 4.5
+ − 681
+ − 682
Constructs a new QScriptValue with a string \a value.
+ − 683
*/
+ − 684
QScriptValue::QScriptValue(const QLatin1String &value)
+ − 685
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 686
{
+ − 687
d_ptr->initFrom(value);
+ − 688
}
+ − 689
+ − 690
/*!
+ − 691
\since 4.5
+ − 692
+ − 693
Constructs a new QScriptValue with a string \a value.
+ − 694
*/
+ − 695
+ − 696
#ifndef QT_NO_CAST_FROM_ASCII
+ − 697
QScriptValue::QScriptValue(const char *value)
+ − 698
: d_ptr(new (/*engine=*/0)QScriptValuePrivate(/*engine=*/0))
+ − 699
{
+ − 700
d_ptr->initFrom(QString::fromAscii(value));
+ − 701
}
+ − 702
#endif
+ − 703
+ − 704
/*!
+ − 705
Assigns the \a other value to this QScriptValue.
+ − 706
+ − 707
Note that if \a other is an object (isObject() returns true),
+ − 708
only a reference to the underlying object will be assigned;
+ − 709
the object itself will not be copied.
+ − 710
*/
+ − 711
QScriptValue &QScriptValue::operator=(const QScriptValue &other)
+ − 712
{
+ − 713
d_ptr = other.d_ptr;
+ − 714
return *this;
+ − 715
}
+ − 716
+ − 717
/*!
+ − 718
Returns true if this QScriptValue is an object of the Error class;
+ − 719
otherwise returns false.
+ − 720
+ − 721
\sa QScriptContext::throwError()
+ − 722
*/
+ − 723
bool QScriptValue::isError() const
+ − 724
{
+ − 725
Q_D(const QScriptValue);
+ − 726
if (!d || !d->isObject())
+ − 727
return false;
+ − 728
return d->jscValue.inherits(&JSC::ErrorInstance::info);
+ − 729
}
+ − 730
+ − 731
/*!
+ − 732
Returns true if this QScriptValue is an object of the Array class;
+ − 733
otherwise returns false.
+ − 734
+ − 735
\sa QScriptEngine::newArray()
+ − 736
*/
+ − 737
bool QScriptValue::isArray() const
+ − 738
{
+ − 739
Q_D(const QScriptValue);
+ − 740
if (!d || !d->isObject())
+ − 741
return false;
+ − 742
return d->jscValue.inherits(&JSC::JSArray::info);
+ − 743
}
+ − 744
+ − 745
/*!
+ − 746
Returns true if this QScriptValue is an object of the Date class;
+ − 747
otherwise returns false.
+ − 748
+ − 749
\sa QScriptEngine::newDate()
+ − 750
*/
+ − 751
bool QScriptValue::isDate() const
+ − 752
{
+ − 753
Q_D(const QScriptValue);
+ − 754
if (!d || !d->isObject())
+ − 755
return false;
+ − 756
return d->jscValue.inherits(&JSC::DateInstance::info);
+ − 757
}
+ − 758
+ − 759
/*!
+ − 760
Returns true if this QScriptValue is an object of the RegExp class;
+ − 761
otherwise returns false.
+ − 762
+ − 763
\sa QScriptEngine::newRegExp()
+ − 764
*/
+ − 765
bool QScriptValue::isRegExp() const
+ − 766
{
+ − 767
Q_D(const QScriptValue);
+ − 768
if (!d || !d->isObject())
+ − 769
return false;
+ − 770
return d->jscValue.inherits(&JSC::RegExpObject::info);
+ − 771
}
+ − 772
+ − 773
/*!
+ − 774
If this QScriptValue is an object, returns the internal prototype
+ − 775
(\c{__proto__} property) of this object; otherwise returns an
+ − 776
invalid QScriptValue.
+ − 777
+ − 778
\sa setPrototype(), isObject()
+ − 779
*/
+ − 780
QScriptValue QScriptValue::prototype() const
+ − 781
{
+ − 782
Q_D(const QScriptValue);
+ − 783
if (!d || !d->isObject())
+ − 784
return QScriptValue();
+ − 785
return d->engine->scriptValueFromJSCValue(JSC::asObject(d->jscValue)->prototype());
+ − 786
}
+ − 787
+ − 788
/*!
+ − 789
If this QScriptValue is an object, sets the internal prototype
+ − 790
(\c{__proto__} property) of this object to be \a prototype;
+ − 791
otherwise does nothing.
+ − 792
+ − 793
The internal prototype should not be confused with the public
+ − 794
property with name "prototype"; the public prototype is usually
+ − 795
only set on functions that act as constructors.
+ − 796
+ − 797
\sa prototype(), isObject()
+ − 798
*/
+ − 799
void QScriptValue::setPrototype(const QScriptValue &prototype)
+ − 800
{
+ − 801
Q_D(QScriptValue);
+ − 802
if (!d || !d->isObject())
+ − 803
return;
+ − 804
if (prototype.isValid() && QScriptValuePrivate::getEngine(prototype)
+ − 805
&& (QScriptValuePrivate::getEngine(prototype) != d->engine)) {
+ − 806
qWarning("QScriptValue::setPrototype() failed: "
+ − 807
"cannot set a prototype created in "
+ − 808
"a different engine");
+ − 809
return;
+ − 810
}
+ − 811
JSC::JSValue other = d->engine->scriptValueToJSCValue(prototype);
+ − 812
+ − 813
// check for cycle
+ − 814
JSC::JSValue nextPrototypeValue = other;
+ − 815
while (nextPrototypeValue && nextPrototypeValue.isObject()) {
+ − 816
JSC::JSObject *nextPrototype = JSC::asObject(nextPrototypeValue);
+ − 817
if (nextPrototype == JSC::asObject(d->jscValue)) {
+ − 818
qWarning("QScriptValue::setPrototype() failed: cyclic prototype value");
+ − 819
return;
+ − 820
}
+ − 821
nextPrototypeValue = nextPrototype->prototype();
+ − 822
}
+ − 823
JSC::asObject(d->jscValue)->setPrototype(other);
+ − 824
}
+ − 825
+ − 826
/*!
+ − 827
\internal
+ − 828
*/
+ − 829
QScriptValue QScriptValue::scope() const
+ − 830
{
+ − 831
Q_D(const QScriptValue);
+ − 832
if (!d || !d->isObject())
+ − 833
return QScriptValue();
+ − 834
// ### make hidden property
+ − 835
return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal);
+ − 836
}
+ − 837
+ − 838
/*!
+ − 839
\internal
+ − 840
*/
+ − 841
void QScriptValue::setScope(const QScriptValue &scope)
+ − 842
{
+ − 843
Q_D(QScriptValue);
+ − 844
if (!d || !d->isObject())
+ − 845
return;
+ − 846
if (scope.isValid() && QScriptValuePrivate::getEngine(scope)
+ − 847
&& (QScriptValuePrivate::getEngine(scope) != d->engine)) {
+ − 848
qWarning("QScriptValue::setScope() failed: "
+ − 849
"cannot set a scope object created in "
+ − 850
"a different engine");
+ − 851
return;
+ − 852
}
+ − 853
JSC::JSValue other = d->engine->scriptValueToJSCValue(scope);
+ − 854
JSC::ExecState *exec = d->engine->currentFrame;
+ − 855
JSC::Identifier id = JSC::Identifier(exec, "__qt_scope__");
+ − 856
if (!scope.isValid()) {
+ − 857
JSC::asObject(d->jscValue)->removeDirect(id);
+ − 858
} else {
+ − 859
// ### make hidden property
+ − 860
JSC::asObject(d->jscValue)->putDirect(id, other);
+ − 861
}
+ − 862
}
+ − 863
+ − 864
/*!
+ − 865
Returns true if this QScriptValue is an instance of
+ − 866
\a other; otherwise returns false.
+ − 867
+ − 868
This QScriptValue is considered to be an instance of \a other if
+ − 869
\a other is a function and the value of the \c{prototype}
+ − 870
property of \a other is in the prototype chain of this
+ − 871
QScriptValue.
+ − 872
*/
+ − 873
bool QScriptValue::instanceOf(const QScriptValue &other) const
+ − 874
{
+ − 875
Q_D(const QScriptValue);
+ − 876
if (!d || !d->isObject() || !other.isObject())
+ − 877
return false;
+ − 878
if (QScriptValuePrivate::getEngine(other) != d->engine) {
+ − 879
qWarning("QScriptValue::instanceof: "
+ − 880
"cannot perform operation on a value created in "
+ − 881
"a different engine");
+ − 882
return false;
+ − 883
}
+ − 884
JSC::JSValue jscProto = d->engine->scriptValueToJSCValue(other.property(QLatin1String("prototype")));
+ − 885
if (!jscProto)
+ − 886
jscProto = JSC::jsUndefined();
+ − 887
JSC::ExecState *exec = d->engine->currentFrame;
+ − 888
JSC::JSValue jscOther = d->engine->scriptValueToJSCValue(other);
+ − 889
return JSC::asObject(jscOther)->hasInstance(exec, d->jscValue, jscProto);
+ − 890
}
+ − 891
+ − 892
// ### move
+ − 893
+ − 894
namespace QScript
+ − 895
{
+ − 896
+ − 897
enum Type {
+ − 898
Undefined,
+ − 899
Null,
+ − 900
Boolean,
+ − 901
String,
+ − 902
Number,
+ − 903
Object
+ − 904
};
+ − 905
+ − 906
static Type type(const QScriptValue &v)
+ − 907
{
+ − 908
if (v.isUndefined())
+ − 909
return Undefined;
+ − 910
else if (v.isNull())
+ − 911
return Null;
+ − 912
else if (v.isBoolean())
+ − 913
return Boolean;
+ − 914
else if (v.isString())
+ − 915
return String;
+ − 916
else if (v.isNumber())
+ − 917
return Number;
+ − 918
Q_ASSERT(v.isObject());
+ − 919
return Object;
+ − 920
}
+ − 921
+ − 922
QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference)
+ − 923
{
+ − 924
Q_ASSERT(object.isObject());
+ − 925
QScriptValuePrivate *pp = QScriptValuePrivate::get(object);
+ − 926
Q_ASSERT(pp->engine != 0);
+ − 927
JSC::ExecState *exec = pp->engine->currentFrame;
+ − 928
JSC::JSValue savedException;
+ − 929
QScriptValuePrivate::saveException(exec, &savedException);
+ − 930
JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint);
+ − 931
QScriptValuePrivate::restoreException(exec, savedException);
+ − 932
return pp->engine->scriptValueFromJSCValue(result);
+ − 933
}
+ − 934
+ − 935
static bool IsNumerical(const QScriptValue &value)
+ − 936
{
+ − 937
return value.isNumber() || value.isBool();
+ − 938
}
+ − 939
+ − 940
static bool LessThan(QScriptValue lhs, QScriptValue rhs)
+ − 941
{
+ − 942
if (type(lhs) == type(rhs)) {
+ − 943
switch (type(lhs)) {
+ − 944
case Undefined:
+ − 945
case Null:
+ − 946
return false;
+ − 947
+ − 948
case Number:
+ − 949
#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
+ − 950
if (qIsNaN(lhs.toNumber()) || qIsNaN(rhs.toNumber()))
+ − 951
return false;
+ − 952
#endif
+ − 953
return lhs.toNumber() < rhs.toNumber();
+ − 954
+ − 955
case Boolean:
+ − 956
return lhs.toBool() < rhs.toBool();
+ − 957
+ − 958
case String:
+ − 959
return lhs.toString() < rhs.toString();
+ − 960
+ − 961
case Object:
+ − 962
break;
+ − 963
} // switch
+ − 964
}
+ − 965
+ − 966
if (lhs.isObject())
+ − 967
lhs = ToPrimitive(lhs, JSC::PreferNumber);
+ − 968
+ − 969
if (rhs.isObject())
+ − 970
rhs = ToPrimitive(rhs, JSC::PreferNumber);
+ − 971
+ − 972
if (lhs.isString() && rhs.isString())
+ − 973
return lhs.toString() < rhs.toString();
+ − 974
+ − 975
qsreal n1 = lhs.toNumber();
+ − 976
qsreal n2 = rhs.toNumber();
+ − 977
#if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
+ − 978
if (qIsNaN(n1) || qIsNaN(n2))
+ − 979
return false;
+ − 980
#endif
+ − 981
return n1 < n2;
+ − 982
}
+ − 983
+ − 984
static bool Equals(QScriptValue lhs, QScriptValue rhs)
+ − 985
{
+ − 986
if (type(lhs) == type(rhs)) {
+ − 987
switch (type(lhs)) {
+ − 988
case QScript::Undefined:
+ − 989
case QScript::Null:
+ − 990
return true;
+ − 991
+ − 992
case QScript::Number:
+ − 993
return lhs.toNumber() == rhs.toNumber();
+ − 994
+ − 995
case QScript::Boolean:
+ − 996
return lhs.toBool() == rhs.toBool();
+ − 997
+ − 998
case QScript::String:
+ − 999
return lhs.toString() == rhs.toString();
+ − 1000
+ − 1001
case QScript::Object:
+ − 1002
if (lhs.isVariant())
+ − 1003
return lhs.strictlyEquals(rhs) || (lhs.toVariant() == rhs.toVariant());
+ − 1004
#ifndef QT_NO_QOBJECT
+ − 1005
else if (lhs.isQObject())
+ − 1006
return (lhs.strictlyEquals(rhs)) || (lhs.toQObject() == rhs.toQObject());
+ − 1007
#endif
+ − 1008
else
+ − 1009
return lhs.strictlyEquals(rhs);
+ − 1010
}
+ − 1011
}
+ − 1012
+ − 1013
if (lhs.isNull() && rhs.isUndefined())
+ − 1014
return true;
+ − 1015
+ − 1016
else if (lhs.isUndefined() && rhs.isNull())
+ − 1017
return true;
+ − 1018
+ − 1019
else if (IsNumerical(lhs) && rhs.isString())
+ − 1020
return lhs.toNumber() == rhs.toNumber();
+ − 1021
+ − 1022
else if (lhs.isString() && IsNumerical(rhs))
+ − 1023
return lhs.toNumber() == rhs.toNumber();
+ − 1024
+ − 1025
else if (lhs.isBool())
+ − 1026
return Equals(lhs.toNumber(), rhs);
+ − 1027
+ − 1028
else if (rhs.isBool())
+ − 1029
return Equals(lhs, rhs.toNumber());
+ − 1030
+ − 1031
else if (lhs.isObject() && !rhs.isNull()) {
+ − 1032
lhs = ToPrimitive(lhs);
+ − 1033
+ − 1034
if (lhs.isValid() && !lhs.isObject())
+ − 1035
return Equals(lhs, rhs);
+ − 1036
}
+ − 1037
+ − 1038
else if (rhs.isObject() && ! lhs.isNull()) {
+ − 1039
rhs = ToPrimitive(rhs);
+ − 1040
if (rhs.isValid() && !rhs.isObject())
+ − 1041
return Equals(lhs, rhs);
+ − 1042
}
+ − 1043
+ − 1044
return false;
+ − 1045
}
+ − 1046
+ − 1047
} // namespace QScript
+ − 1048
+ − 1049
/*!
+ − 1050
Returns true if this QScriptValue is less than \a other, otherwise
+ − 1051
returns false. The comparison follows the behavior described in
+ − 1052
\l{ECMA-262} section 11.8.5, "The Abstract Relational Comparison
+ − 1053
Algorithm".
+ − 1054
+ − 1055
Note that if this QScriptValue or the \a other value are objects,
+ − 1056
calling this function has side effects on the script engine, since
+ − 1057
the engine will call the object's valueOf() function (and possibly
+ − 1058
toString()) in an attempt to convert the object to a primitive value
+ − 1059
(possibly resulting in an uncaught script exception).
+ − 1060
+ − 1061
\sa equals()
+ − 1062
*/
+ − 1063
bool QScriptValue::lessThan(const QScriptValue &other) const
+ − 1064
{
+ − 1065
Q_D(const QScriptValue);
+ − 1066
// no equivalent function in JSC? There's a jsLess() in VM/Machine.cpp
+ − 1067
if (!isValid() || !other.isValid())
+ − 1068
return false;
+ − 1069
if (QScriptValuePrivate::getEngine(other) && d->engine
+ − 1070
&& (QScriptValuePrivate::getEngine(other) != d->engine)) {
+ − 1071
qWarning("QScriptValue::lessThan: "
+ − 1072
"cannot compare to a value created in "
+ − 1073
"a different engine");
+ − 1074
return false;
+ − 1075
}
+ − 1076
return QScript::LessThan(*this, other);
+ − 1077
}
+ − 1078
+ − 1079
/*!
+ − 1080
Returns true if this QScriptValue is equal to \a other, otherwise
+ − 1081
returns false. The comparison follows the behavior described in
+ − 1082
\l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
+ − 1083
Algorithm".
+ − 1084
+ − 1085
This function can return true even if the type of this QScriptValue
+ − 1086
is different from the type of the \a other value; i.e. the
+ − 1087
comparison is not strict. For example, comparing the number 9 to
+ − 1088
the string "9" returns true; comparing an undefined value to a null
+ − 1089
value returns true; comparing a \c{Number} object whose primitive
+ − 1090
value is 6 to a \c{String} object whose primitive value is "6"
+ − 1091
returns true; and comparing the number 1 to the boolean value
+ − 1092
\c{true} returns true. If you want to perform a comparison
+ − 1093
without such implicit value conversion, use strictlyEquals().
+ − 1094
+ − 1095
Note that if this QScriptValue or the \a other value are objects,
+ − 1096
calling this function has side effects on the script engine, since
+ − 1097
the engine will call the object's valueOf() function (and possibly
+ − 1098
toString()) in an attempt to convert the object to a primitive value
+ − 1099
(possibly resulting in an uncaught script exception).
+ − 1100
+ − 1101
\sa strictlyEquals(), lessThan()
+ − 1102
*/
+ − 1103
bool QScriptValue::equals(const QScriptValue &other) const
+ − 1104
{
+ − 1105
Q_D(const QScriptValue);
+ − 1106
if (!d || !other.d_ptr)
+ − 1107
return (d_ptr == other.d_ptr);
+ − 1108
if (QScriptValuePrivate::getEngine(other) && d->engine
+ − 1109
&& (QScriptValuePrivate::getEngine(other) != d->engine)) {
+ − 1110
qWarning("QScriptValue::equals: "
+ − 1111
"cannot compare to a value created in "
+ − 1112
"a different engine");
+ − 1113
return false;
+ − 1114
}
+ − 1115
if (d->isJSC() && other.d_ptr->isJSC()) {
+ − 1116
QScriptEnginePrivate *eng_p = d->engine;
+ − 1117
if (!eng_p)
+ − 1118
eng_p = other.d_ptr->engine;
+ − 1119
if (eng_p) {
+ − 1120
JSC::ExecState *exec = eng_p->currentFrame;
+ − 1121
JSC::JSValue savedException;
+ − 1122
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1123
bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue);
+ − 1124
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1125
return result;
+ − 1126
}
+ − 1127
}
+ − 1128
return QScript::Equals(*this, other);
+ − 1129
}
+ − 1130
+ − 1131
/*!
+ − 1132
Returns true if this QScriptValue is equal to \a other using strict
+ − 1133
comparison (no conversion), otherwise returns false. The comparison
+ − 1134
follows the behavior described in \l{ECMA-262} section 11.9.6, "The
+ − 1135
Strict Equality Comparison Algorithm".
+ − 1136
+ − 1137
If the type of this QScriptValue is different from the type of the
+ − 1138
\a other value, this function returns false. If the types are equal,
+ − 1139
the result depends on the type, as shown in the following table:
+ − 1140
+ − 1141
\table
+ − 1142
\header \o Type \o Result
+ − 1143
\row \o Undefined \o true
+ − 1144
\row \o Null \o true
+ − 1145
\row \o Boolean \o true if both values are true, false otherwise
+ − 1146
\row \o Number \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
+ − 1147
\row \o String \o true if both values are exactly the same sequence of characters, false otherwise
+ − 1148
\row \o Object \o true if both values refer to the same object, false otherwise
+ − 1149
\endtable
+ − 1150
+ − 1151
\sa equals()
+ − 1152
*/
+ − 1153
bool QScriptValue::strictlyEquals(const QScriptValue &other) const
+ − 1154
{
+ − 1155
Q_D(const QScriptValue);
+ − 1156
if (!d || !other.d_ptr)
+ − 1157
return (d_ptr == other.d_ptr);
+ − 1158
if (QScriptValuePrivate::getEngine(other) && d->engine
+ − 1159
&& (QScriptValuePrivate::getEngine(other) != d->engine)) {
+ − 1160
qWarning("QScriptValue::strictlyEquals: "
+ − 1161
"cannot compare to a value created in "
+ − 1162
"a different engine");
+ − 1163
return false;
+ − 1164
}
+ − 1165
+ − 1166
if (d->type != other.d_ptr->type) {
+ − 1167
if (d->type == QScriptValuePrivate::JavaScriptCore)
+ − 1168
return JSC::JSValue::strictEqual(d->jscValue, d->engine->scriptValueToJSCValue(other));
+ − 1169
else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore)
+ − 1170
return JSC::JSValue::strictEqual(other.d_ptr->engine->scriptValueToJSCValue(*this), other.d_ptr->jscValue);
+ − 1171
+ − 1172
return false;
+ − 1173
}
+ − 1174
switch (d->type) {
+ − 1175
case QScriptValuePrivate::JavaScriptCore:
+ − 1176
return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue);
+ − 1177
case QScriptValuePrivate::Number:
+ − 1178
return (d->numberValue == other.d_ptr->numberValue);
+ − 1179
case QScriptValuePrivate::String:
+ − 1180
return (d->stringValue == other.d_ptr->stringValue);
+ − 1181
}
+ − 1182
return false;
+ − 1183
}
+ − 1184
+ − 1185
/*!
+ − 1186
Returns the string value of this QScriptValue, as defined in
+ − 1187
\l{ECMA-262} section 9.8, "ToString".
+ − 1188
+ − 1189
Note that if this QScriptValue is an object, calling this function
+ − 1190
has side effects on the script engine, since the engine will call
+ − 1191
the object's toString() function (and possibly valueOf()) in an
+ − 1192
attempt to convert the object to a primitive value (possibly
+ − 1193
resulting in an uncaught script exception).
+ − 1194
+ − 1195
\sa isString()
+ − 1196
*/
+ − 1197
QString QScriptValue::toString() const
+ − 1198
{
+ − 1199
Q_D(const QScriptValue);
+ − 1200
if (!d)
+ − 1201
return QString();
+ − 1202
switch (d->type) {
+ − 1203
case QScriptValuePrivate::JavaScriptCore: {
+ − 1204
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1205
JSC::JSValue savedException;
+ − 1206
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1207
JSC::UString str = d->jscValue.toString(exec);
+ − 1208
if (exec && exec->hadException() && !str.size()) {
+ − 1209
JSC::JSValue savedException2;
+ − 1210
QScriptValuePrivate::saveException(exec, &savedException2);
+ − 1211
str = savedException2.toString(exec);
+ − 1212
QScriptValuePrivate::restoreException(exec, savedException2);
+ − 1213
}
+ − 1214
if (savedException)
+ − 1215
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1216
return str;
+ − 1217
}
+ − 1218
case QScriptValuePrivate::Number:
+ − 1219
return JSC::UString::from(d->numberValue);
+ − 1220
case QScriptValuePrivate::String:
+ − 1221
return d->stringValue;
+ − 1222
}
+ − 1223
return QString();
+ − 1224
}
+ − 1225
+ − 1226
/*!
+ − 1227
Returns the number value of this QScriptValue, as defined in
+ − 1228
\l{ECMA-262} section 9.3, "ToNumber".
+ − 1229
+ − 1230
Note that if this QScriptValue is an object, calling this function
+ − 1231
has side effects on the script engine, since the engine will call
+ − 1232
the object's valueOf() function (and possibly toString()) in an
+ − 1233
attempt to convert the object to a primitive value (possibly
+ − 1234
resulting in an uncaught script exception).
+ − 1235
+ − 1236
\sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16()
+ − 1237
*/
+ − 1238
qsreal QScriptValue::toNumber() const
+ − 1239
{
+ − 1240
Q_D(const QScriptValue);
+ − 1241
if (!d)
+ − 1242
return 0;
+ − 1243
switch (d->type) {
+ − 1244
case QScriptValuePrivate::JavaScriptCore: {
+ − 1245
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1246
JSC::JSValue savedException;
+ − 1247
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1248
qsreal result = d->jscValue.toNumber(exec);
+ − 1249
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1250
return result;
+ − 1251
}
+ − 1252
case QScriptValuePrivate::Number:
+ − 1253
return d->numberValue;
+ − 1254
case QScriptValuePrivate::String:
+ − 1255
return ((JSC::UString)d->stringValue).toDouble();
+ − 1256
}
+ − 1257
return 0;
+ − 1258
}
+ − 1259
+ − 1260
/*!
+ − 1261
\obsolete
+ − 1262
+ − 1263
Use toBool() instead.
+ − 1264
*/
+ − 1265
bool QScriptValue::toBoolean() const
+ − 1266
{
+ − 1267
Q_D(const QScriptValue);
+ − 1268
if (!d)
+ − 1269
return false;
+ − 1270
switch (d->type) {
+ − 1271
case QScriptValuePrivate::JavaScriptCore: {
+ − 1272
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1273
JSC::JSValue savedException;
+ − 1274
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1275
bool result = d->jscValue.toBoolean(exec);
+ − 1276
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1277
return result;
+ − 1278
}
+ − 1279
case QScriptValuePrivate::Number:
+ − 1280
return (d->numberValue != 0) && !qIsNaN(d->numberValue);
+ − 1281
case QScriptValuePrivate::String:
+ − 1282
return (!d->stringValue.isEmpty());
+ − 1283
}
+ − 1284
return false;
+ − 1285
}
+ − 1286
+ − 1287
/*!
+ − 1288
\since 4.5
+ − 1289
+ − 1290
Returns the boolean value of this QScriptValue, using the conversion
+ − 1291
rules described in \l{ECMA-262} section 9.2, "ToBoolean".
+ − 1292
+ − 1293
Note that if this QScriptValue is an object, calling this function
+ − 1294
has side effects on the script engine, since the engine will call
+ − 1295
the object's valueOf() function (and possibly toString()) in an
+ − 1296
attempt to convert the object to a primitive value (possibly
+ − 1297
resulting in an uncaught script exception).
+ − 1298
+ − 1299
\sa isBool()
+ − 1300
*/
+ − 1301
bool QScriptValue::toBool() const
+ − 1302
{
+ − 1303
Q_D(const QScriptValue);
+ − 1304
if (!d)
+ − 1305
return false;
+ − 1306
switch (d->type) {
+ − 1307
case QScriptValuePrivate::JavaScriptCore: {
+ − 1308
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1309
JSC::JSValue savedException;
+ − 1310
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1311
bool result = d->jscValue.toBoolean(exec);
+ − 1312
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1313
return result;
+ − 1314
}
+ − 1315
case QScriptValuePrivate::Number:
+ − 1316
return (d->numberValue != 0) && !qIsNaN(d->numberValue);
+ − 1317
case QScriptValuePrivate::String:
+ − 1318
return (!d->stringValue.isEmpty());
+ − 1319
}
+ − 1320
return false;
+ − 1321
}
+ − 1322
+ − 1323
/*!
+ − 1324
Returns the signed 32-bit integer value of this QScriptValue, using
+ − 1325
the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32".
+ − 1326
+ − 1327
Note that if this QScriptValue is an object, calling this function
+ − 1328
has side effects on the script engine, since the engine will call
+ − 1329
the object's valueOf() function (and possibly toString()) in an
+ − 1330
attempt to convert the object to a primitive value (possibly
+ − 1331
resulting in an uncaught script exception).
+ − 1332
+ − 1333
\sa toNumber(), toUInt32()
+ − 1334
*/
+ − 1335
qint32 QScriptValue::toInt32() const
+ − 1336
{
+ − 1337
Q_D(const QScriptValue);
+ − 1338
if (!d)
+ − 1339
return 0;
+ − 1340
switch (d->type) {
+ − 1341
case QScriptValuePrivate::JavaScriptCore: {
+ − 1342
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1343
JSC::JSValue savedException;
+ − 1344
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1345
qint32 result = d->jscValue.toInt32(exec);
+ − 1346
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1347
return result;
+ − 1348
}
+ − 1349
case QScriptValuePrivate::Number:
+ − 1350
return QScript::ToInt32(d->numberValue);
+ − 1351
case QScriptValuePrivate::String:
+ − 1352
return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble());
+ − 1353
}
+ − 1354
return 0;
+ − 1355
}
+ − 1356
+ − 1357
/*!
+ − 1358
Returns the unsigned 32-bit integer value of this QScriptValue, using
+ − 1359
the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32".
+ − 1360
+ − 1361
Note that if this QScriptValue is an object, calling this function
+ − 1362
has side effects on the script engine, since the engine will call
+ − 1363
the object's valueOf() function (and possibly toString()) in an
+ − 1364
attempt to convert the object to a primitive value (possibly
+ − 1365
resulting in an uncaught script exception).
+ − 1366
+ − 1367
\sa toNumber(), toInt32()
+ − 1368
*/
+ − 1369
quint32 QScriptValue::toUInt32() const
+ − 1370
{
+ − 1371
Q_D(const QScriptValue);
+ − 1372
if (!d)
+ − 1373
return 0;
+ − 1374
switch (d->type) {
+ − 1375
case QScriptValuePrivate::JavaScriptCore: {
+ − 1376
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1377
JSC::JSValue savedException;
+ − 1378
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1379
quint32 result = d->jscValue.toUInt32(exec);
+ − 1380
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1381
return result;
+ − 1382
}
+ − 1383
case QScriptValuePrivate::Number:
+ − 1384
return QScript::ToUint32(d->numberValue);
+ − 1385
case QScriptValuePrivate::String:
+ − 1386
return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble());
+ − 1387
}
+ − 1388
return 0;
+ − 1389
}
+ − 1390
+ − 1391
/*!
+ − 1392
Returns the unsigned 16-bit integer value of this QScriptValue, using
+ − 1393
the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16".
+ − 1394
+ − 1395
Note that if this QScriptValue is an object, calling this function
+ − 1396
has side effects on the script engine, since the engine will call
+ − 1397
the object's valueOf() function (and possibly toString()) in an
+ − 1398
attempt to convert the object to a primitive value (possibly
+ − 1399
resulting in an uncaught script exception).
+ − 1400
+ − 1401
\sa toNumber()
+ − 1402
*/
+ − 1403
quint16 QScriptValue::toUInt16() const
+ − 1404
{
+ − 1405
Q_D(const QScriptValue);
+ − 1406
if (!d)
+ − 1407
return 0;
+ − 1408
switch (d->type) {
+ − 1409
case QScriptValuePrivate::JavaScriptCore: {
+ − 1410
// ### no equivalent function in JSC
+ − 1411
return QScript::ToUint16(toNumber());
+ − 1412
}
+ − 1413
case QScriptValuePrivate::Number:
+ − 1414
return QScript::ToUint16(d->numberValue);
+ − 1415
case QScriptValuePrivate::String:
+ − 1416
return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble());
+ − 1417
}
+ − 1418
return 0;
+ − 1419
}
+ − 1420
+ − 1421
/*!
+ − 1422
Returns the integer value of this QScriptValue, using the conversion
+ − 1423
rules described in \l{ECMA-262} section 9.4, "ToInteger".
+ − 1424
+ − 1425
Note that if this QScriptValue is an object, calling this function
+ − 1426
has side effects on the script engine, since the engine will call
+ − 1427
the object's valueOf() function (and possibly toString()) in an
+ − 1428
attempt to convert the object to a primitive value (possibly
+ − 1429
resulting in an uncaught script exception).
+ − 1430
+ − 1431
\sa toNumber()
+ − 1432
*/
+ − 1433
qsreal QScriptValue::toInteger() const
+ − 1434
{
+ − 1435
Q_D(const QScriptValue);
+ − 1436
if (!d)
+ − 1437
return 0;
+ − 1438
switch (d->type) {
+ − 1439
case QScriptValuePrivate::JavaScriptCore: {
+ − 1440
JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0;
+ − 1441
JSC::JSValue savedException;
+ − 1442
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1443
qsreal result = d->jscValue.toInteger(exec);
+ − 1444
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1445
return result;
+ − 1446
}
+ − 1447
case QScriptValuePrivate::Number:
+ − 1448
return QScript::ToInteger(d->numberValue);
+ − 1449
case QScriptValuePrivate::String:
+ − 1450
return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble());
+ − 1451
}
+ − 1452
return 0;
+ − 1453
}
+ − 1454
+ − 1455
/*!
+ − 1456
Returns the QVariant value of this QScriptValue, if it can be
+ − 1457
converted to a QVariant; otherwise returns an invalid QVariant.
+ − 1458
The conversion is performed according to the following table:
+ − 1459
+ − 1460
\table
+ − 1461
\header \o Input Type \o Result
+ − 1462
\row \o Undefined \o An invalid QVariant.
+ − 1463
\row \o Null \o An invalid QVariant.
+ − 1464
\row \o Boolean \o A QVariant containing the value of the boolean.
+ − 1465
\row \o Number \o A QVariant containing the value of the number.
+ − 1466
\row \o String \o A QVariant containing the value of the string.
+ − 1467
\row \o QVariant Object \o The result is the QVariant value of the object (no conversion).
+ − 1468
\row \o QObject Object \o A QVariant containing a pointer to the QObject.
+ − 1469
\row \o Date Object \o A QVariant containing the date value (toDateTime()).
+ − 1470
\row \o RegExp Object \o A QVariant containing the regular expression value (toRegExp()).
+ − 1471
\row \o Array Object \o The array is converted to a QVariantList.
+ − 1472
\row \o Object \o If the value is primitive, then the result is converted to a QVariant according to the above rules; otherwise, an invalid QVariant is returned.
+ − 1473
\endtable
+ − 1474
+ − 1475
\sa isVariant()
+ − 1476
*/
+ − 1477
QVariant QScriptValue::toVariant() const
+ − 1478
{
+ − 1479
Q_D(const QScriptValue);
+ − 1480
if (!d)
+ − 1481
return QVariant();
+ − 1482
switch (d->type) {
+ − 1483
case QScriptValuePrivate::JavaScriptCore:
+ − 1484
if (isObject()) {
+ − 1485
if (isVariant())
+ − 1486
return d->variantValue();
+ − 1487
#ifndef QT_NO_QOBJECT
+ − 1488
else if (isQObject())
+ − 1489
return qVariantFromValue(toQObject());
+ − 1490
#endif
+ − 1491
else if (isDate())
+ − 1492
return QVariant(toDateTime());
+ − 1493
#ifndef QT_NO_REGEXP
+ − 1494
else if (isRegExp())
+ − 1495
return QVariant(toRegExp());
+ − 1496
#endif
+ − 1497
else if (isArray())
+ − 1498
return QScriptEnginePrivate::variantListFromArray(*this);
+ − 1499
// try to convert to primitive
+ − 1500
JSC::ExecState *exec = d->engine->currentFrame;
+ − 1501
JSC::JSValue savedException;
+ − 1502
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1503
JSC::JSValue prim = d->jscValue.toPrimitive(exec);
+ − 1504
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1505
if (!prim.isObject())
+ − 1506
return d->engine->scriptValueFromJSCValue(prim).toVariant();
+ − 1507
} else if (isNumber()) {
+ − 1508
return QVariant(toNumber());
+ − 1509
} else if (isString()) {
+ − 1510
return QVariant(toString());
+ − 1511
} else if (isBool()) {
+ − 1512
return QVariant(toBool());
+ − 1513
}
+ − 1514
return QVariant();
+ − 1515
case QScriptValuePrivate::Number:
+ − 1516
return QVariant(d->numberValue);
+ − 1517
case QScriptValuePrivate::String:
+ − 1518
return QVariant(d->stringValue);
+ − 1519
}
+ − 1520
return QVariant();
+ − 1521
}
+ − 1522
+ − 1523
/*!
+ − 1524
\obsolete
+ − 1525
+ − 1526
This function is obsolete; use QScriptEngine::toObject() instead.
+ − 1527
*/
+ − 1528
QScriptValue QScriptValue::toObject() const
+ − 1529
{
+ − 1530
Q_D(const QScriptValue);
+ − 1531
if (!d || !d->engine)
+ − 1532
return QScriptValue();
+ − 1533
return engine()->toObject(*this);
+ − 1534
}
+ − 1535
+ − 1536
/*!
+ − 1537
Returns a QDateTime representation of this value, in local time.
+ − 1538
If this QScriptValue is not a date, or the value of the date is NaN
+ − 1539
(Not-a-Number), an invalid QDateTime is returned.
+ − 1540
+ − 1541
\sa isDate()
+ − 1542
*/
+ − 1543
QDateTime QScriptValue::toDateTime() const
+ − 1544
{
+ − 1545
Q_D(const QScriptValue);
+ − 1546
if (!isDate())
+ − 1547
return QDateTime();
+ − 1548
qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(d->jscValue))->internalNumber();
+ − 1549
return QScript::ToDateTime(t, Qt::LocalTime);
+ − 1550
}
+ − 1551
+ − 1552
#ifndef QT_NO_REGEXP
+ − 1553
/*!
+ − 1554
Returns the QRegExp representation of this value.
+ − 1555
If this QScriptValue is not a regular expression, an empty
+ − 1556
QRegExp is returned.
+ − 1557
+ − 1558
\sa isRegExp()
+ − 1559
*/
+ − 1560
QRegExp QScriptValue::toRegExp() const
+ − 1561
{
+ − 1562
Q_D(const QScriptValue);
+ − 1563
if (!isRegExp())
+ − 1564
return QRegExp();
+ − 1565
QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString();
+ − 1566
Qt::CaseSensitivity kase = Qt::CaseSensitive;
+ − 1567
if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool())
+ − 1568
kase = Qt::CaseInsensitive;
+ − 1569
return QRegExp(pattern, kase, QRegExp::RegExp2);
+ − 1570
}
+ − 1571
#endif // QT_NO_REGEXP
+ − 1572
+ − 1573
/*!
+ − 1574
If this QScriptValue is a QObject, returns the QObject pointer
+ − 1575
that the QScriptValue represents; otherwise, returns 0.
+ − 1576
+ − 1577
If the QObject that this QScriptValue wraps has been deleted,
+ − 1578
this function returns 0 (i.e. it is possible for toQObject()
+ − 1579
to return 0 even when isQObject() returns true).
+ − 1580
+ − 1581
\sa isQObject()
+ − 1582
*/
+ − 1583
QObject *QScriptValue::toQObject() const
+ − 1584
{
+ − 1585
Q_D(const QScriptValue);
+ − 1586
if (isQObject()) {
+ − 1587
QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 1588
return static_cast<QScript::QObjectDelegate*>(object->delegate())->value();
+ − 1589
} else if (isVariant()) {
+ − 1590
QVariant var = toVariant();
+ − 1591
int type = var.userType();
+ − 1592
if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar))
+ − 1593
return *reinterpret_cast<QObject* const *>(var.constData());
+ − 1594
}
+ − 1595
return 0;
+ − 1596
}
+ − 1597
+ − 1598
/*!
+ − 1599
If this QScriptValue is a QMetaObject, returns the QMetaObject pointer
+ − 1600
that the QScriptValue represents; otherwise, returns 0.
+ − 1601
+ − 1602
\sa isQMetaObject()
+ − 1603
*/
+ − 1604
const QMetaObject *QScriptValue::toQMetaObject() const
+ − 1605
{
+ − 1606
Q_D(const QScriptValue);
+ − 1607
if (isQMetaObject())
+ − 1608
return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(d->jscValue))->value();
+ − 1609
return 0;
+ − 1610
}
+ − 1611
+ − 1612
/*!
+ − 1613
Sets the value of this QScriptValue's property with the given \a name to
+ − 1614
the given \a value.
+ − 1615
+ − 1616
If this QScriptValue is not an object, this function does nothing.
+ − 1617
+ − 1618
If this QScriptValue does not already have a property with name \a name,
+ − 1619
a new property is created; the given \a flags then specify how this
+ − 1620
property may be accessed by script code.
+ − 1621
+ − 1622
If \a value is invalid, the property is removed.
+ − 1623
+ − 1624
If the property is implemented using a setter function (i.e. has the
+ − 1625
PropertySetter flag set), calling setProperty() has side-effects on
+ − 1626
the script engine, since the setter function will be called with the
+ − 1627
given \a value as argument (possibly resulting in an uncaught script
+ − 1628
exception).
+ − 1629
+ − 1630
Note that you cannot specify custom getter or setter functions for
+ − 1631
built-in properties, such as the \c{length} property of Array objects
+ − 1632
or meta properties of QObject objects.
+ − 1633
+ − 1634
\sa property()
+ − 1635
*/
+ − 1636
+ − 1637
void QScriptValue::setProperty(const QString &name, const QScriptValue &value,
+ − 1638
const PropertyFlags &flags)
+ − 1639
{
+ − 1640
Q_D(QScriptValue);
+ − 1641
if (!d || !d->isObject())
+ − 1642
return;
+ − 1643
JSC::ExecState *exec = d->engine->currentFrame;
+ − 1644
d->setProperty(JSC::Identifier(exec, name), value, flags);
+ − 1645
}
+ − 1646
+ − 1647
/*!
+ − 1648
Returns the value of this QScriptValue's property with the given \a name,
+ − 1649
using the given \a mode to resolve the property.
+ − 1650
+ − 1651
If no such property exists, an invalid QScriptValue is returned.
+ − 1652
+ − 1653
If the property is implemented using a getter function (i.e. has the
+ − 1654
PropertyGetter flag set), calling property() has side-effects on the
+ − 1655
script engine, since the getter function will be called (possibly
+ − 1656
resulting in an uncaught script exception). If an exception
+ − 1657
occurred, property() returns the value that was thrown (typically
+ − 1658
an \c{Error} object).
+ − 1659
+ − 1660
\sa setProperty(), propertyFlags(), QScriptValueIterator
+ − 1661
*/
+ − 1662
QScriptValue QScriptValue::property(const QString &name,
+ − 1663
const ResolveFlags &mode) const
+ − 1664
{
+ − 1665
Q_D(const QScriptValue);
+ − 1666
if (!d || !d->isObject())
+ − 1667
return QScriptValue();
+ − 1668
return d->property(name, mode);
+ − 1669
}
+ − 1670
+ − 1671
/*!
+ − 1672
\overload
+ − 1673
+ − 1674
Returns the property at the given \a arrayIndex, using the given \a
+ − 1675
mode to resolve the property.
+ − 1676
+ − 1677
This function is provided for convenience and performance when
+ − 1678
working with array objects.
+ − 1679
+ − 1680
If this QScriptValue is not an Array object, this function behaves
+ − 1681
as if property() was called with the string representation of \a
+ − 1682
arrayIndex.
+ − 1683
*/
+ − 1684
QScriptValue QScriptValue::property(quint32 arrayIndex,
+ − 1685
const ResolveFlags &mode) const
+ − 1686
{
+ − 1687
Q_D(const QScriptValue);
+ − 1688
if (!d || !d->isObject())
+ − 1689
return QScriptValue();
+ − 1690
return d->property(arrayIndex, mode);
+ − 1691
}
+ − 1692
+ − 1693
/*!
+ − 1694
\overload
+ − 1695
+ − 1696
Sets the property at the given \a arrayIndex to the given \a value.
+ − 1697
+ − 1698
This function is provided for convenience and performance when
+ − 1699
working with array objects.
+ − 1700
+ − 1701
If this QScriptValue is not an Array object, this function behaves
+ − 1702
as if setProperty() was called with the string representation of \a
+ − 1703
arrayIndex.
+ − 1704
*/
+ − 1705
void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value,
+ − 1706
const PropertyFlags &flags)
+ − 1707
{
+ − 1708
Q_D(QScriptValue);
+ − 1709
if (!d || !d->isObject())
+ − 1710
return;
+ − 1711
if (QScriptValuePrivate::getEngine(value)
+ − 1712
&& (QScriptValuePrivate::getEngine(value) != d->engine)) {
+ − 1713
qWarning("QScriptValue::setProperty() failed: "
+ − 1714
"cannot set value created in a different engine");
+ − 1715
return;
+ − 1716
}
+ − 1717
JSC::ExecState *exec = d->engine->currentFrame;
+ − 1718
JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value);
+ − 1719
if (!jscValue) {
+ − 1720
JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex, /*checkDontDelete=*/false);
+ − 1721
} else {
+ − 1722
if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) {
+ − 1723
// fall back to string-based setProperty(), since there is no
+ − 1724
// JSC::JSObject::defineGetter(unsigned)
+ − 1725
d->setProperty(JSC::Identifier::from(exec, arrayIndex), value, flags);
+ − 1726
} else {
+ − 1727
if (flags != QScriptValue::KeepExistingFlags) {
+ − 1728
// if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex))
+ − 1729
// JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex);
+ − 1730
unsigned attribs = 0;
+ − 1731
if (flags & QScriptValue::ReadOnly)
+ − 1732
attribs |= JSC::ReadOnly;
+ − 1733
if (flags & QScriptValue::SkipInEnumeration)
+ − 1734
attribs |= JSC::DontEnum;
+ − 1735
if (flags & QScriptValue::Undeletable)
+ − 1736
attribs |= JSC::DontDelete;
+ − 1737
attribs |= flags & QScriptValue::UserRange;
+ − 1738
JSC::asObject(d->jscValue)->putWithAttributes(exec, arrayIndex, jscValue, attribs);
+ − 1739
} else {
+ − 1740
JSC::asObject(d->jscValue)->put(exec, arrayIndex, jscValue);
+ − 1741
}
+ − 1742
}
+ − 1743
}
+ − 1744
}
+ − 1745
+ − 1746
/*!
+ − 1747
\since 4.4
+ − 1748
+ − 1749
Returns the value of this QScriptValue's property with the given \a name,
+ − 1750
using the given \a mode to resolve the property.
+ − 1751
+ − 1752
This overload of property() is useful when you need to look up the
+ − 1753
same property repeatedly, since the lookup can be performed faster
+ − 1754
when the name is represented as an interned string.
+ − 1755
+ − 1756
\sa QScriptEngine::toStringHandle(), setProperty()
+ − 1757
*/
+ − 1758
QScriptValue QScriptValue::property(const QScriptString &name,
+ − 1759
const ResolveFlags &mode) const
+ − 1760
{
+ − 1761
Q_D(const QScriptValue);
+ − 1762
if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
+ − 1763
return QScriptValue();
+ − 1764
return d->property(name.d_ptr->identifier, mode);
+ − 1765
}
+ − 1766
+ − 1767
/*!
+ − 1768
\since 4.4
+ − 1769
+ − 1770
Sets the value of this QScriptValue's property with the given \a
+ − 1771
name to the given \a value. The given \a flags specify how this
+ − 1772
property may be accessed by script code.
+ − 1773
+ − 1774
This overload of setProperty() is useful when you need to set the
+ − 1775
same property repeatedly, since the operation can be performed
+ − 1776
faster when the name is represented as an interned string.
+ − 1777
+ − 1778
\sa QScriptEngine::toStringHandle()
+ − 1779
*/
+ − 1780
void QScriptValue::setProperty(const QScriptString &name,
+ − 1781
const QScriptValue &value,
+ − 1782
const PropertyFlags &flags)
+ − 1783
{
+ − 1784
Q_D(QScriptValue);
+ − 1785
if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
+ − 1786
return;
+ − 1787
d->setProperty(name.d_ptr->identifier, value, flags);
+ − 1788
}
+ − 1789
+ − 1790
/*!
+ − 1791
Returns the flags of the property with the given \a name, using the
+ − 1792
given \a mode to resolve the property.
+ − 1793
+ − 1794
\sa property()
+ − 1795
*/
+ − 1796
QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString &name,
+ − 1797
const ResolveFlags &mode) const
+ − 1798
{
+ − 1799
Q_D(const QScriptValue);
+ − 1800
if (!d || !d->isObject())
+ − 1801
return 0;
+ − 1802
JSC::ExecState *exec = d->engine->currentFrame;
+ − 1803
return d->propertyFlags(JSC::Identifier(exec, name), mode);
+ − 1804
+ − 1805
}
+ − 1806
+ − 1807
/*!
+ − 1808
\since 4.4
+ − 1809
+ − 1810
Returns the flags of the property with the given \a name, using the
+ − 1811
given \a mode to resolve the property.
+ − 1812
+ − 1813
\sa property()
+ − 1814
*/
+ − 1815
QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString &name,
+ − 1816
const ResolveFlags &mode) const
+ − 1817
{
+ − 1818
Q_D(const QScriptValue);
+ − 1819
if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name))
+ − 1820
return 0;
+ − 1821
return d->propertyFlags(name.d_ptr->identifier, mode);
+ − 1822
}
+ − 1823
+ − 1824
/*!
+ − 1825
Calls this QScriptValue as a function, using \a thisObject as
+ − 1826
the `this' object in the function call, and passing \a args
+ − 1827
as arguments to the function. Returns the value returned from
+ − 1828
the function.
+ − 1829
+ − 1830
If this QScriptValue is not a function, call() does nothing
+ − 1831
and returns an invalid QScriptValue.
+ − 1832
+ − 1833
Note that if \a thisObject is not an object, the global object
+ − 1834
(see \l{QScriptEngine::globalObject()}) will be used as the
+ − 1835
`this' object.
+ − 1836
+ − 1837
Calling call() can cause an exception to occur in the script engine;
+ − 1838
in that case, call() returns the value that was thrown (typically an
+ − 1839
\c{Error} object). You can call
+ − 1840
QScriptEngine::hasUncaughtException() to determine if an exception
+ − 1841
occurred.
+ − 1842
+ − 1843
\snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2
+ − 1844
+ − 1845
\sa construct()
+ − 1846
*/
+ − 1847
QScriptValue QScriptValue::call(const QScriptValue &thisObject,
+ − 1848
const QScriptValueList &args)
+ − 1849
{
+ − 1850
Q_D(const QScriptValue);
+ − 1851
if (!d || !d->isJSC())
+ − 1852
return QScriptValue();
+ − 1853
JSC::JSValue callee = d->jscValue;
+ − 1854
JSC::CallData callData;
+ − 1855
JSC::CallType callType = callee.getCallData(callData);
+ − 1856
if (callType == JSC::CallTypeNone)
+ − 1857
return QScriptValue();
+ − 1858
+ − 1859
if (QScriptValuePrivate::getEngine(thisObject)
+ − 1860
&& (QScriptValuePrivate::getEngine(thisObject) != d->engine)) {
+ − 1861
qWarning("QScriptValue::call() failed: "
+ − 1862
"cannot call function with thisObject created in "
+ − 1863
"a different engine");
+ − 1864
return QScriptValue();
+ − 1865
}
+ − 1866
+ − 1867
JSC::ExecState *exec = d->engine->currentFrame;
+ − 1868
+ − 1869
JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject);
+ − 1870
if (!jscThisObject || !jscThisObject.isObject())
+ − 1871
jscThisObject = d->engine->globalObject();
+ − 1872
+ − 1873
QVarLengthArray<JSC::JSValue, 8> argsVector(args.size());
+ − 1874
for (int i = 0; i < args.size(); ++i) {
+ − 1875
const QScriptValue &arg = args.at(i);
+ − 1876
if (!arg.isValid()) {
+ − 1877
argsVector[i] = JSC::jsUndefined();
+ − 1878
} else if (QScriptValuePrivate::getEngine(arg)
+ − 1879
&& (QScriptValuePrivate::getEngine(arg) != d->engine)) {
+ − 1880
qWarning("QScriptValue::call() failed: "
+ − 1881
"cannot call function with argument created in "
+ − 1882
"a different engine");
+ − 1883
return QScriptValue();
+ − 1884
} else {
+ − 1885
argsVector[i] = d->engine->scriptValueToJSCValue(arg);
+ − 1886
}
+ − 1887
}
+ − 1888
JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
+ − 1889
+ − 1890
JSC::JSValue savedException;
+ − 1891
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1892
JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs);
+ − 1893
if (exec->hadException()) {
+ − 1894
result = exec->exception();
+ − 1895
} else {
+ − 1896
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1897
}
+ − 1898
return d->engine->scriptValueFromJSCValue(result);
+ − 1899
}
+ − 1900
+ − 1901
/*!
+ − 1902
Calls this QScriptValue as a function, using \a thisObject as
+ − 1903
the `this' object in the function call, and passing \a arguments
+ − 1904
as arguments to the function. Returns the value returned from
+ − 1905
the function.
+ − 1906
+ − 1907
If this QScriptValue is not a function, call() does nothing
+ − 1908
and returns an invalid QScriptValue.
+ − 1909
+ − 1910
\a arguments can be an arguments object, an array, null or
+ − 1911
undefined; any other type will cause a TypeError to be thrown.
+ − 1912
+ − 1913
Note that if \a thisObject is not an object, the global object
+ − 1914
(see \l{QScriptEngine::globalObject()}) will be used as the
+ − 1915
`this' object.
+ − 1916
+ − 1917
One common usage of this function is to forward native function
+ − 1918
calls to another function:
+ − 1919
+ − 1920
\snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 3
+ − 1921
+ − 1922
\sa construct(), QScriptContext::argumentsObject()
+ − 1923
*/
+ − 1924
QScriptValue QScriptValue::call(const QScriptValue &thisObject,
+ − 1925
const QScriptValue &arguments)
+ − 1926
{
+ − 1927
Q_D(QScriptValue);
+ − 1928
if (!d || !d->isJSC())
+ − 1929
return QScriptValue();
+ − 1930
JSC::JSValue callee = d->jscValue;
+ − 1931
JSC::CallData callData;
+ − 1932
JSC::CallType callType = callee.getCallData(callData);
+ − 1933
if (callType == JSC::CallTypeNone)
+ − 1934
return QScriptValue();
+ − 1935
+ − 1936
if (QScriptValuePrivate::getEngine(thisObject)
+ − 1937
&& (QScriptValuePrivate::getEngine(thisObject) != d->engine)) {
+ − 1938
qWarning("QScriptValue::call() failed: "
+ − 1939
"cannot call function with thisObject created in "
+ − 1940
"a different engine");
+ − 1941
return QScriptValue();
+ − 1942
}
+ − 1943
+ − 1944
JSC::ExecState *exec = d->engine->currentFrame;
+ − 1945
+ − 1946
JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject);
+ − 1947
if (!jscThisObject || !jscThisObject.isObject())
+ − 1948
jscThisObject = d->engine->globalObject();
+ − 1949
+ − 1950
JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments);
+ − 1951
// copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
+ − 1952
JSC::MarkedArgumentBuffer applyArgs;
+ − 1953
if (!array.isUndefinedOrNull()) {
+ − 1954
if (!array.isObject()) {
+ − 1955
return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError));
+ − 1956
}
+ − 1957
if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
+ − 1958
JSC::asArguments(array)->fillArgList(exec, applyArgs);
+ − 1959
else if (JSC::isJSArray(&exec->globalData(), array))
+ − 1960
JSC::asArray(array)->fillArgList(exec, applyArgs);
+ − 1961
else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) {
+ − 1962
unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
+ − 1963
for (unsigned i = 0; i < length; ++i)
+ − 1964
applyArgs.append(JSC::asArray(array)->get(exec, i));
+ − 1965
} else {
+ − 1966
Q_ASSERT_X(false, Q_FUNC_INFO, "implement me");
+ − 1967
// return JSC::throwError(exec, JSC::TypeError);
+ − 1968
}
+ − 1969
}
+ − 1970
+ − 1971
JSC::JSValue savedException;
+ − 1972
QScriptValuePrivate::saveException(exec, &savedException);
+ − 1973
JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs);
+ − 1974
if (exec->hadException()) {
+ − 1975
result = exec->exception();
+ − 1976
} else {
+ − 1977
QScriptValuePrivate::restoreException(exec, savedException);
+ − 1978
}
+ − 1979
return d->engine->scriptValueFromJSCValue(result);
+ − 1980
}
+ − 1981
+ − 1982
/*!
+ − 1983
Creates a new \c{Object} and calls this QScriptValue as a
+ − 1984
constructor, using the created object as the `this' object and
+ − 1985
passing \a args as arguments. If the return value from the
+ − 1986
constructor call is an object, then that object is returned;
+ − 1987
otherwise the default constructed object is returned.
+ − 1988
+ − 1989
If this QScriptValue is not a function, construct() does nothing
+ − 1990
and returns an invalid QScriptValue.
+ − 1991
+ − 1992
Calling construct() can cause an exception to occur in the script
+ − 1993
engine; in that case, construct() returns the value that was thrown
+ − 1994
(typically an \c{Error} object). You can call
+ − 1995
QScriptEngine::hasUncaughtException() to determine if an exception
+ − 1996
occurred.
+ − 1997
+ − 1998
\sa call(), QScriptEngine::newObject()
+ − 1999
*/
+ − 2000
QScriptValue QScriptValue::construct(const QScriptValueList &args)
+ − 2001
{
+ − 2002
Q_D(const QScriptValue);
+ − 2003
if (!d || !d->isJSC())
+ − 2004
return QScriptValue();
+ − 2005
JSC::JSValue callee = d->jscValue;
+ − 2006
JSC::ConstructData constructData;
+ − 2007
JSC::ConstructType constructType = callee.getConstructData(constructData);
+ − 2008
if (constructType == JSC::ConstructTypeNone)
+ − 2009
return QScriptValue();
+ − 2010
+ − 2011
JSC::ExecState *exec = d->engine->currentFrame;
+ − 2012
+ − 2013
QVarLengthArray<JSC::JSValue, 8> argsVector(args.size());
+ − 2014
for (int i = 0; i < args.size(); ++i) {
+ − 2015
if (!args.at(i).isValid())
+ − 2016
argsVector[i] = JSC::jsUndefined();
+ − 2017
else
+ − 2018
argsVector[i] = d->engine->scriptValueToJSCValue(args.at(i));
+ − 2019
}
+ − 2020
+ − 2021
JSC::ArgList jscArgs(argsVector.data(), argsVector.size());
+ − 2022
+ − 2023
JSC::JSValue savedException;
+ − 2024
QScriptValuePrivate::saveException(exec, &savedException);
+ − 2025
JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs);
+ − 2026
if (exec->hadException()) {
+ − 2027
result = JSC::asObject(exec->exception());
+ − 2028
} else {
+ − 2029
QScriptValuePrivate::restoreException(exec, savedException);
+ − 2030
}
+ − 2031
return d->engine->scriptValueFromJSCValue(result);
+ − 2032
}
+ − 2033
+ − 2034
/*!
+ − 2035
Creates a new \c{Object} and calls this QScriptValue as a
+ − 2036
constructor, using the created object as the `this' object and
+ − 2037
passing \a arguments as arguments. If the return value from the
+ − 2038
constructor call is an object, then that object is returned;
+ − 2039
otherwise the default constructed object is returned.
+ − 2040
+ − 2041
If this QScriptValue is not a function, construct() does nothing
+ − 2042
and returns an invalid QScriptValue.
+ − 2043
+ − 2044
\a arguments can be an arguments object, an array, null or
+ − 2045
undefined. Any other type will cause a TypeError to be thrown.
+ − 2046
+ − 2047
\sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject()
+ − 2048
*/
+ − 2049
QScriptValue QScriptValue::construct(const QScriptValue &arguments)
+ − 2050
{
+ − 2051
Q_D(QScriptValue);
+ − 2052
if (!d || !d->isJSC())
+ − 2053
return QScriptValue();
+ − 2054
JSC::JSValue callee = d->jscValue;
+ − 2055
JSC::ConstructData constructData;
+ − 2056
JSC::ConstructType constructType = callee.getConstructData(constructData);
+ − 2057
if (constructType == JSC::ConstructTypeNone)
+ − 2058
return QScriptValue();
+ − 2059
+ − 2060
JSC::ExecState *exec = d->engine->currentFrame;
+ − 2061
+ − 2062
JSC::JSValue array = d->engine->scriptValueToJSCValue(arguments);
+ − 2063
// copied from runtime/FunctionPrototype.cpp, functionProtoFuncApply()
+ − 2064
JSC::MarkedArgumentBuffer applyArgs;
+ − 2065
if (!array.isUndefinedOrNull()) {
+ − 2066
if (!array.isObject()) {
+ − 2067
return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
+ − 2068
}
+ − 2069
if (JSC::asObject(array)->classInfo() == &JSC::Arguments::info)
+ − 2070
JSC::asArguments(array)->fillArgList(exec, applyArgs);
+ − 2071
else if (JSC::isJSArray(&exec->globalData(), array))
+ − 2072
JSC::asArray(array)->fillArgList(exec, applyArgs);
+ − 2073
else if (JSC::asObject(array)->inherits(&JSC::JSArray::info)) {
+ − 2074
unsigned length = JSC::asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
+ − 2075
for (unsigned i = 0; i < length; ++i)
+ − 2076
applyArgs.append(JSC::asArray(array)->get(exec, i));
+ − 2077
} else {
+ − 2078
return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array"));
+ − 2079
}
+ − 2080
}
+ − 2081
+ − 2082
JSC::JSValue savedException;
+ − 2083
QScriptValuePrivate::saveException(exec, &savedException);
+ − 2084
JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs);
+ − 2085
if (exec->hadException()) {
+ − 2086
if (exec->exception().isObject())
+ − 2087
result = JSC::asObject(exec->exception());
+ − 2088
} else {
+ − 2089
QScriptValuePrivate::restoreException(exec, savedException);
+ − 2090
}
+ − 2091
return d->engine->scriptValueFromJSCValue(result);
+ − 2092
}
+ − 2093
+ − 2094
/*!
+ − 2095
Returns the QScriptEngine that created this QScriptValue,
+ − 2096
or 0 if this QScriptValue is invalid or the value is not
+ − 2097
associated with a particular engine.
+ − 2098
*/
+ − 2099
QScriptEngine *QScriptValue::engine() const
+ − 2100
{
+ − 2101
Q_D(const QScriptValue);
+ − 2102
if (!d)
+ − 2103
return 0;
+ − 2104
return QScriptEnginePrivate::get(d->engine);
+ − 2105
}
+ − 2106
+ − 2107
/*!
+ − 2108
\obsolete
+ − 2109
+ − 2110
Use isBool() instead.
+ − 2111
*/
+ − 2112
bool QScriptValue::isBoolean() const
+ − 2113
{
+ − 2114
Q_D(const QScriptValue);
+ − 2115
return d && d->isJSC() && d->jscValue.isBoolean();
+ − 2116
}
+ − 2117
+ − 2118
/*!
+ − 2119
\since 4.5
+ − 2120
+ − 2121
Returns true if this QScriptValue is of the primitive type Boolean;
+ − 2122
otherwise returns false.
+ − 2123
+ − 2124
\sa toBool()
+ − 2125
*/
+ − 2126
bool QScriptValue::isBool() const
+ − 2127
{
+ − 2128
Q_D(const QScriptValue);
+ − 2129
return d && d->isJSC() && d->jscValue.isBoolean();
+ − 2130
}
+ − 2131
+ − 2132
/*!
+ − 2133
Returns true if this QScriptValue is of the primitive type Number;
+ − 2134
otherwise returns false.
+ − 2135
+ − 2136
\sa toNumber()
+ − 2137
*/
+ − 2138
bool QScriptValue::isNumber() const
+ − 2139
{
+ − 2140
Q_D(const QScriptValue);
+ − 2141
if (!d)
+ − 2142
return false;
+ − 2143
switch (d->type) {
+ − 2144
case QScriptValuePrivate::JavaScriptCore:
+ − 2145
return d->jscValue.isNumber();
+ − 2146
case QScriptValuePrivate::Number:
+ − 2147
return true;
+ − 2148
case QScriptValuePrivate::String:
+ − 2149
return false;
+ − 2150
}
+ − 2151
return false;
+ − 2152
}
+ − 2153
+ − 2154
/*!
+ − 2155
Returns true if this QScriptValue is of the primitive type String;
+ − 2156
otherwise returns false.
+ − 2157
+ − 2158
\sa toString()
+ − 2159
*/
+ − 2160
bool QScriptValue::isString() const
+ − 2161
{
+ − 2162
Q_D(const QScriptValue);
+ − 2163
if (!d)
+ − 2164
return false;
+ − 2165
switch (d->type) {
+ − 2166
case QScriptValuePrivate::JavaScriptCore:
+ − 2167
return d->jscValue.isString();
+ − 2168
case QScriptValuePrivate::Number:
+ − 2169
return false;
+ − 2170
case QScriptValuePrivate::String:
+ − 2171
return true;
+ − 2172
}
+ − 2173
return false;
+ − 2174
}
+ − 2175
+ − 2176
/*!
+ − 2177
Returns true if this QScriptValue is a function; otherwise returns
+ − 2178
false.
+ − 2179
+ − 2180
\sa call()
+ − 2181
*/
+ − 2182
bool QScriptValue::isFunction() const
+ − 2183
{
+ − 2184
Q_D(const QScriptValue);
+ − 2185
if (!d || !d->isJSC())
+ − 2186
return false;
+ − 2187
return QScript::isFunction(d->jscValue);
+ − 2188
}
+ − 2189
+ − 2190
/*!
+ − 2191
Returns true if this QScriptValue is of the primitive type Null;
+ − 2192
otherwise returns false.
+ − 2193
+ − 2194
\sa QScriptEngine::nullValue()
+ − 2195
*/
+ − 2196
bool QScriptValue::isNull() const
+ − 2197
{
+ − 2198
Q_D(const QScriptValue);
+ − 2199
return d && d->isJSC() && d->jscValue.isNull();
+ − 2200
}
+ − 2201
+ − 2202
/*!
+ − 2203
Returns true if this QScriptValue is of the primitive type Undefined;
+ − 2204
otherwise returns false.
+ − 2205
+ − 2206
\sa QScriptEngine::undefinedValue()
+ − 2207
*/
+ − 2208
bool QScriptValue::isUndefined() const
+ − 2209
{
+ − 2210
Q_D(const QScriptValue);
+ − 2211
return d && d->isJSC() && d->jscValue.isUndefined();
+ − 2212
}
+ − 2213
+ − 2214
/*!
+ − 2215
Returns true if this QScriptValue is of the Object type; otherwise
+ − 2216
returns false.
+ − 2217
+ − 2218
Note that function values, variant values, and QObject values are
+ − 2219
objects, so this function returns true for such values.
+ − 2220
+ − 2221
\sa toObject(), QScriptEngine::newObject()
+ − 2222
*/
+ − 2223
bool QScriptValue::isObject() const
+ − 2224
{
+ − 2225
Q_D(const QScriptValue);
+ − 2226
return d && d->isObject();
+ − 2227
}
+ − 2228
+ − 2229
/*!
+ − 2230
Returns true if this QScriptValue is a variant value;
+ − 2231
otherwise returns false.
+ − 2232
+ − 2233
\sa toVariant(), QScriptEngine::newVariant()
+ − 2234
*/
+ − 2235
bool QScriptValue::isVariant() const
+ − 2236
{
+ − 2237
Q_D(const QScriptValue);
+ − 2238
if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
+ − 2239
return false;
+ − 2240
QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 2241
QScriptObjectDelegate *delegate = object->delegate();
+ − 2242
return (delegate && (delegate->type() == QScriptObjectDelegate::Variant));
+ − 2243
}
+ − 2244
+ − 2245
/*!
+ − 2246
Returns true if this QScriptValue is a QObject; otherwise returns
+ − 2247
false.
+ − 2248
+ − 2249
Note: This function returns true even if the QObject that this
+ − 2250
QScriptValue wraps has been deleted.
+ − 2251
+ − 2252
\sa toQObject(), QScriptEngine::newQObject()
+ − 2253
*/
+ − 2254
bool QScriptValue::isQObject() const
+ − 2255
{
+ − 2256
Q_D(const QScriptValue);
+ − 2257
if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
+ − 2258
return false;
+ − 2259
QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 2260
QScriptObjectDelegate *delegate = object->delegate();
+ − 2261
return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject));
+ − 2262
}
+ − 2263
+ − 2264
/*!
+ − 2265
Returns true if this QScriptValue is a QMetaObject; otherwise returns
+ − 2266
false.
+ − 2267
+ − 2268
\sa toQMetaObject(), QScriptEngine::newQMetaObject()
+ − 2269
*/
+ − 2270
bool QScriptValue::isQMetaObject() const
+ − 2271
{
+ − 2272
Q_D(const QScriptValue);
+ − 2273
if (!d || !d->isObject())
+ − 2274
return false;
+ − 2275
return JSC::asObject(d->jscValue)->inherits(&QScript::QMetaObjectWrapperObject::info);
+ − 2276
}
+ − 2277
+ − 2278
/*!
+ − 2279
Returns true if this QScriptValue is valid; otherwise returns
+ − 2280
false.
+ − 2281
*/
+ − 2282
bool QScriptValue::isValid() const
+ − 2283
{
+ − 2284
Q_D(const QScriptValue);
+ − 2285
return d && (!d->isJSC() || !!d->jscValue);
+ − 2286
}
+ − 2287
+ − 2288
/*!
+ − 2289
\since 4.4
+ − 2290
+ − 2291
Returns the internal data of this QScriptValue object. QtScript uses
+ − 2292
this property to store the primitive value of Date, String, Number
+ − 2293
and Boolean objects. For other types of object, custom data may be
+ − 2294
stored using setData().
+ − 2295
*/
+ − 2296
QScriptValue QScriptValue::data() const
+ − 2297
{
+ − 2298
Q_D(const QScriptValue);
+ − 2299
if (!d || !d->isObject())
+ − 2300
return QScriptValue();
+ − 2301
if (d->jscValue.inherits(&QScriptObject::info)) {
+ − 2302
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 2303
return d->engine->scriptValueFromJSCValue(scriptObject->data());
+ − 2304
} else {
+ − 2305
// ### make hidden property
+ − 2306
return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal);
+ − 2307
}
+ − 2308
}
+ − 2309
+ − 2310
/*!
+ − 2311
\since 4.4
+ − 2312
+ − 2313
Sets the internal \a data of this QScriptValue object. You can use
+ − 2314
this function to set object-specific data that won't be directly
+ − 2315
accessible to scripts, but may be retrieved in C++ using the data()
+ − 2316
function.
+ − 2317
*/
+ − 2318
void QScriptValue::setData(const QScriptValue &data)
+ − 2319
{
+ − 2320
Q_D(QScriptValue);
+ − 2321
if (!d || !d->isObject())
+ − 2322
return;
+ − 2323
JSC::JSValue other = d->engine->scriptValueToJSCValue(data);
+ − 2324
if (d->jscValue.inherits(&QScriptObject::info)) {
+ − 2325
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 2326
scriptObject->setData(other);
+ − 2327
} else {
+ − 2328
JSC::ExecState *exec = d->engine->currentFrame;
+ − 2329
JSC::Identifier id = JSC::Identifier(exec, "__qt_data__");
+ − 2330
if (!data.isValid()) {
+ − 2331
JSC::asObject(d->jscValue)->removeDirect(id);
+ − 2332
} else {
+ − 2333
// ### make hidden property
+ − 2334
JSC::asObject(d->jscValue)->putDirect(id, other);
+ − 2335
}
+ − 2336
}
+ − 2337
}
+ − 2338
+ − 2339
/*!
+ − 2340
\since 4.4
+ − 2341
+ − 2342
Returns the custom script class that this script object is an
+ − 2343
instance of, or 0 if the object is not of a custom class.
+ − 2344
+ − 2345
\sa setScriptClass()
+ − 2346
*/
+ − 2347
QScriptClass *QScriptValue::scriptClass() const
+ − 2348
{
+ − 2349
Q_D(const QScriptValue);
+ − 2350
if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info))
+ − 2351
return 0;
+ − 2352
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 2353
QScriptObjectDelegate *delegate = scriptObject->delegate();
+ − 2354
if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject))
+ − 2355
return 0;
+ − 2356
return static_cast<QScript::ClassObjectDelegate*>(delegate)->scriptClass();
+ − 2357
}
+ − 2358
+ − 2359
/*!
+ − 2360
\since 4.4
+ − 2361
+ − 2362
Sets the custom script class of this script object to \a scriptClass.
+ − 2363
This can be used to "promote" a plain script object (e.g. created
+ − 2364
by the "new" operator in a script, or by QScriptEngine::newObject() in C++)
+ − 2365
to an object of a custom type.
+ − 2366
+ − 2367
If \a scriptClass is 0, the object will be demoted to a plain
+ − 2368
script object.
+ − 2369
+ − 2370
\sa scriptClass(), setData()
+ − 2371
*/
+ − 2372
void QScriptValue::setScriptClass(QScriptClass *scriptClass)
+ − 2373
{
+ − 2374
Q_D(QScriptValue);
+ − 2375
if (!d || !d->isObject())
+ − 2376
return;
+ − 2377
if (!d->jscValue.inherits(&QScriptObject::info)) {
+ − 2378
qWarning("QScriptValue::setScriptClass() failed: "
+ − 2379
"cannot change class of non-QScriptObject");
+ − 2380
return;
+ − 2381
}
+ − 2382
QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue));
+ − 2383
if (!scriptClass) {
+ − 2384
scriptObject->setDelegate(0);
+ − 2385
} else {
+ − 2386
QScriptObjectDelegate *delegate = scriptObject->delegate();
+ − 2387
if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject)) {
+ − 2388
delegate = new QScript::ClassObjectDelegate(scriptClass);
+ − 2389
scriptObject->setDelegate(delegate);
+ − 2390
}
+ − 2391
static_cast<QScript::ClassObjectDelegate*>(delegate)->setScriptClass(scriptClass);
+ − 2392
}
+ − 2393
}
+ − 2394
+ − 2395
/*!
+ − 2396
\internal
+ − 2397
+ − 2398
Returns the ID of this object, or -1 if this QScriptValue is not an
+ − 2399
object.
+ − 2400
+ − 2401
\sa QScriptEngine::objectById()
+ − 2402
*/
+ − 2403
qint64 QScriptValue::objectId() const
+ − 2404
{
+ − 2405
return d_ptr?d_ptr->objectId():-1;
+ − 2406
}
+ − 2407
QT_END_NAMESPACE