1/*
2    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301, USA.
18*/
19
20#include "config.h"
21
22#include "qscriptvalue.h"
23
24#include "qscriptengine.h"
25#include "qscriptengine_p.h"
26#include "qscriptvalue_p.h"
27#include <QtCore/qdebug.h>
28
29/*!
30    Constructs an invalid value.
31*/
32QScriptValue::QScriptValue()
33    : d_ptr(new QScriptValuePrivate())
34{
35}
36
37/*!
38  Constructs a new QScriptValue with a boolean \a value.
39*/
40QScriptValue::QScriptValue(bool value)
41    : d_ptr(new QScriptValuePrivate(value))
42{
43}
44
45/*!
46  Constructs a new QScriptValue with a number \a value.
47*/
48QScriptValue::QScriptValue(int value)
49    : d_ptr(new QScriptValuePrivate(value))
50{
51}
52
53/*!
54  Constructs a new QScriptValue with a number \a value.
55*/
56QScriptValue::QScriptValue(uint value)
57    : d_ptr(new QScriptValuePrivate(value))
58{
59}
60
61/*!
62  Constructs a new QScriptValue with a number \a value.
63*/
64QScriptValue::QScriptValue(qsreal value)
65    : d_ptr(new QScriptValuePrivate(value))
66{
67}
68
69/*!
70  Constructs a new QScriptValue with a string \a value.
71*/
72QScriptValue::QScriptValue(const QString& value)
73    : d_ptr(new QScriptValuePrivate(value))
74{
75}
76
77/*!
78  Constructs a new QScriptValue with a special \a value.
79*/
80QScriptValue::QScriptValue(SpecialValue value)
81    : d_ptr(new QScriptValuePrivate(value))
82{
83}
84
85/*!
86  Constructs a new QScriptValue with a string \a value.
87*/
88QScriptValue::QScriptValue(const char* value)
89    : d_ptr(new QScriptValuePrivate(QString::fromUtf8(value)))
90{
91}
92
93/*!
94    Block automatic convertion to bool
95    \internal
96*/
97QScriptValue::QScriptValue(void* d)
98{
99    Q_ASSERT(false);
100}
101
102/*!
103    Constructs a new QScriptValue from private
104    \internal
105*/
106QScriptValue::QScriptValue(QScriptValuePrivate* d)
107    : d_ptr(d)
108{
109}
110
111/*!
112  \obsolete
113
114  Constructs a new QScriptValue with the boolean \a value and
115  registers it with the script \a engine.
116*/
117QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
118{
119    if (engine)
120        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
121    else
122        d_ptr = new QScriptValuePrivate(value);
123}
124
125/*!
126  \obsolete
127
128  Constructs a new QScriptValue with the integer \a value and
129  registers it with the script \a engine.
130*/
131QScriptValue::QScriptValue(QScriptEngine* engine, int value)
132{
133    if (engine)
134        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
135    else
136        d_ptr = new QScriptValuePrivate(value);
137}
138
139/*!
140  \obsolete
141
142  Constructs a new QScriptValue with the unsigned integer \a value and
143  registers it with the script \a engine.
144 */
145QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
146{
147    if (engine)
148        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
149    else
150        d_ptr = new QScriptValuePrivate(value);
151}
152
153/*!
154  \obsolete
155
156  Constructs a new QScriptValue with the qsreal \a value and
157  registers it with the script \a engine.
158*/
159QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
160{
161    if (engine)
162        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
163    else
164        d_ptr = new QScriptValuePrivate(value);
165}
166
167/*!
168  \obsolete
169
170  Constructs a new QScriptValue with the string \a value and
171  registers it with the script \a engine.
172*/
173QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
174{
175    if (engine)
176        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
177    else
178        d_ptr = new QScriptValuePrivate(value);
179}
180
181/*!
182  \obsolete
183
184  Constructs a new QScriptValue with the string \a value and
185  registers it with the script \a engine.
186*/
187QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
188{
189    if (engine)
190        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), QString::fromUtf8(value));
191    else
192        d_ptr = new QScriptValuePrivate(QString::fromUtf8(value));
193}
194
195/*!
196  \obsolete
197
198  Constructs a new QScriptValue with the special \a value and
199  registers it with the script \a engine.
200*/
201QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value)
202{
203    if (engine)
204        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
205    else
206        d_ptr = new QScriptValuePrivate(value);
207}
208
209/*!
210  Constructs a new QScriptValue that is a copy of \a other.
211
212  Note that if \a other is an object (i.e., isObject() would return
213  true), then only a reference to the underlying object is copied into
214  the new script value (i.e., the object itself is not copied).
215*/
216QScriptValue::QScriptValue(const QScriptValue& other)
217    : d_ptr(other.d_ptr)
218{
219}
220
221/*!
222    Destroys this QScriptValue.
223*/
224QScriptValue::~QScriptValue()
225{
226}
227
228/*!
229  Returns true if this QScriptValue is valid; otherwise returns
230  false.
231*/
232bool QScriptValue::isValid() const
233{
234    return d_ptr->isValid();
235}
236
237/*!
238  Returns true if this QScriptValue is of the primitive type Boolean;
239  otherwise returns false.
240
241  \sa toBool()
242*/
243bool QScriptValue::isBool() const
244{
245    return d_ptr->isBool();
246}
247
248/*!
249  \obsolete
250
251  Use isBool() instead.
252  Returns true if this QScriptValue is of the primitive type Boolean;
253  otherwise returns false.
254*/
255bool QScriptValue::isBoolean() const
256{
257    return d_ptr->isBool();
258}
259
260/*!
261  Returns true if this QScriptValue is of the primitive type Number;
262  otherwise returns false.
263
264  \sa toNumber()
265*/
266bool QScriptValue::isNumber() const
267{
268    return d_ptr->isNumber();
269}
270
271/*!
272  Returns true if this QScriptValue is of the primitive type Null;
273  otherwise returns false.
274
275  \sa QScriptEngine::nullValue()
276*/
277bool QScriptValue::isNull() const
278{
279    return d_ptr->isNull();
280}
281
282/*!
283  Returns true if this QScriptValue is of the primitive type String;
284  otherwise returns false.
285
286  \sa toString()
287*/
288bool QScriptValue::isString() const
289{
290    return d_ptr->isString();
291}
292
293/*!
294  Returns true if this QScriptValue is of the primitive type Undefined;
295  otherwise returns false.
296
297  \sa QScriptEngine::undefinedValue()
298*/
299bool QScriptValue::isUndefined() const
300{
301    return d_ptr->isUndefined();
302}
303
304/*!
305  Returns true if this QScriptValue is an object of the Error class;
306  otherwise returns false.
307
308  \sa QScriptContext::throwError()
309*/
310bool QScriptValue::isError() const
311{
312    return d_ptr->isError();
313}
314
315/*!
316  Returns true if this QScriptValue is an object of the Array class;
317  otherwise returns false.
318
319  \sa QScriptEngine::newArray()
320*/
321bool QScriptValue::isArray() const
322{
323    return d_ptr->isArray();
324}
325
326/*!
327    Returns true if this QScriptValue is an object of the Date class;
328    otherwise returns false.
329
330    \sa QScriptEngine::newDate()
331*/
332bool QScriptValue::isDate() const
333{
334    return d_ptr->isDate();
335}
336
337/*!
338  Returns true if this QScriptValue is of the Object type; otherwise
339  returns false.
340
341  Note that function values, variant values, and QObject values are
342  objects, so this function returns true for such values.
343
344  \sa toObject(), QScriptEngine::newObject()
345*/
346bool QScriptValue::isObject() const
347{
348    return d_ptr->isObject();
349}
350
351/*!
352  Returns true if this QScriptValue is a function; otherwise returns
353  false.
354
355  \sa call()
356*/
357bool QScriptValue::isFunction() const
358{
359    return d_ptr->isFunction();
360}
361
362/*!
363  Returns the string value of this QScriptValue, as defined in
364  \l{ECMA-262} section 9.8, "ToString".
365
366  Note that if this QScriptValue is an object, calling this function
367  has side effects on the script engine, since the engine will call
368  the object's toString() function (and possibly valueOf()) in an
369  attempt to convert the object to a primitive value (possibly
370  resulting in an uncaught script exception).
371
372  \sa isString()
373*/
374QString QScriptValue::toString() const
375{
376    return d_ptr->toString();
377}
378
379/*!
380  Returns the number value of this QScriptValue, as defined in
381  \l{ECMA-262} section 9.3, "ToNumber".
382
383  Note that if this QScriptValue is an object, calling this function
384  has side effects on the script engine, since the engine will call
385  the object's valueOf() function (and possibly toString()) in an
386  attempt to convert the object to a primitive value (possibly
387  resulting in an uncaught script exception).
388
389  \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16()
390*/
391qsreal QScriptValue::toNumber() const
392{
393    return d_ptr->toNumber();
394}
395
396/*!
397  Returns the boolean value of this QScriptValue, using the conversion
398  rules described in \l{ECMA-262} section 9.2, "ToBoolean".
399
400  Note that if this QScriptValue is an object, calling this function
401  has side effects on the script engine, since the engine will call
402  the object's valueOf() function (and possibly toString()) in an
403  attempt to convert the object to a primitive value (possibly
404  resulting in an uncaught script exception).
405
406  \sa isBool()
407*/
408bool QScriptValue::toBool() const
409{
410    return d_ptr->toBool();
411}
412
413/*!
414  \obsolete
415
416  Use toBool() instead.
417*/
418bool QScriptValue::toBoolean() const
419{
420    return d_ptr->toBool();
421}
422
423/*!
424  Returns the integer value of this QScriptValue, using the conversion
425  rules described in \l{ECMA-262} section 9.4, "ToInteger".
426
427  Note that if this QScriptValue is an object, calling this function
428  has side effects on the script engine, since the engine will call
429  the object's valueOf() function (and possibly toString()) in an
430  attempt to convert the object to a primitive value (possibly
431  resulting in an uncaught script exception).
432
433  \sa toNumber()
434*/
435qsreal QScriptValue::toInteger() const
436{
437    return d_ptr->toInteger();
438}
439
440/*!
441  Returns the signed 32-bit integer value of this QScriptValue, using
442  the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32".
443
444  Note that if this QScriptValue is an object, calling this function
445  has side effects on the script engine, since the engine will call
446  the object's valueOf() function (and possibly toString()) in an
447  attempt to convert the object to a primitive value (possibly
448  resulting in an uncaught script exception).
449
450  \sa toNumber(), toUInt32()
451*/
452qint32 QScriptValue::toInt32() const
453{
454    return d_ptr->toInt32();
455}
456
457/*!
458  Returns the unsigned 32-bit integer value of this QScriptValue, using
459  the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32".
460
461  Note that if this QScriptValue is an object, calling this function
462  has side effects on the script engine, since the engine will call
463  the object's valueOf() function (and possibly toString()) in an
464  attempt to convert the object to a primitive value (possibly
465  resulting in an uncaught script exception).
466
467  \sa toNumber(), toInt32()
468*/
469quint32 QScriptValue::toUInt32() const
470{
471    return d_ptr->toUInt32();
472}
473
474/*!
475  Returns the unsigned 16-bit integer value of this QScriptValue, using
476  the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16".
477
478  Note that if this QScriptValue is an object, calling this function
479  has side effects on the script engine, since the engine will call
480  the object's valueOf() function (and possibly toString()) in an
481  attempt to convert the object to a primitive value (possibly
482  resulting in an uncaught script exception).
483
484  \sa toNumber()
485*/
486quint16 QScriptValue::toUInt16() const
487{
488    return d_ptr->toUInt16();
489}
490
491/*!
492  \obsolete
493
494  This function is obsolete; use QScriptEngine::toObject() instead.
495*/
496QScriptValue QScriptValue::toObject() const
497{
498    return QScriptValuePrivate::get(d_ptr->toObject());
499}
500
501/*!
502    Returns a QDateTime representation of this value, in local time.
503    If this QScriptValue is not a date, or the value of the date is
504    NaN (Not-a-Number), an invalid QDateTime is returned.
505
506    \sa isDate()
507*/
508QDateTime QScriptValue::toDateTime() const
509{
510    return d_ptr->toDateTime();
511}
512
513/*!
514  Calls this QScriptValue as a function, using \a thisObject as
515  the `this' object in the function call, and passing \a args
516  as arguments to the function. Returns the value returned from
517  the function.
518
519  If this QScriptValue is not a function, call() does nothing
520  and returns an invalid QScriptValue.
521
522  Note that if \a thisObject is not an object, the global object
523  (see \l{QScriptEngine::globalObject()}) will be used as the
524  `this' object.
525
526  Calling call() can cause an exception to occur in the script engine;
527  in that case, call() returns the value that was thrown (typically an
528  \c{Error} object). You can call
529  QScriptEngine::hasUncaughtException() to determine if an exception
530  occurred.
531
532  \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2
533
534  \sa construct()
535*/
536QScriptValue QScriptValue::call(const QScriptValue& thisObject, const QScriptValueList& args)
537{
538    return d_ptr->call(thisObject.d_ptr.data(), args);
539}
540
541/*!
542  Returns the QScriptEngine that created this QScriptValue,
543  or 0 if this QScriptValue is invalid or the value is not
544  associated with a particular engine.
545*/
546QScriptEngine* QScriptValue::engine() const
547{
548    QScriptEnginePrivate* engine = d_ptr->engine();
549    if (engine)
550        return QScriptEnginePrivate::get(engine);
551    return 0;
552}
553
554/*!
555  If this QScriptValue is an object, returns the internal prototype
556  (\c{__proto__} property) of this object; otherwise returns an
557  invalid QScriptValue.
558
559  \sa setPrototype(), isObject()
560*/
561QScriptValue QScriptValue::prototype() const
562{
563    return QScriptValuePrivate::get(d_ptr->prototype());
564}
565
566/*!
567  If this QScriptValue is an object, sets the internal prototype
568  (\c{__proto__} property) of this object to be \a prototype;
569  otherwise does nothing.
570
571  The internal prototype should not be confused with the public
572  property with name "prototype"; the public prototype is usually
573  only set on functions that act as constructors.
574
575  \sa prototype(), isObject()
576*/
577void QScriptValue::setPrototype(const QScriptValue& prototype)
578{
579    d_ptr->setPrototype(QScriptValuePrivate::get(prototype));
580}
581
582/*!
583  Assigns the \a other value to this QScriptValue.
584
585  Note that if \a other is an object (isObject() returns true),
586  only a reference to the underlying object will be assigned;
587  the object itself will not be copied.
588*/
589QScriptValue& QScriptValue::operator=(const QScriptValue& other)
590{
591    d_ptr = other.d_ptr;
592    return *this;
593}
594
595/*!
596  Returns true if this QScriptValue is equal to \a other, otherwise
597  returns false. The comparison follows the behavior described in
598  \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
599  Algorithm".
600
601  This function can return true even if the type of this QScriptValue
602  is different from the type of the \a other value; i.e. the
603  comparison is not strict.  For example, comparing the number 9 to
604  the string "9" returns true; comparing an undefined value to a null
605  value returns true; comparing a \c{Number} object whose primitive
606  value is 6 to a \c{String} object whose primitive value is "6"
607  returns true; and comparing the number 1 to the boolean value
608  \c{true} returns true. If you want to perform a comparison
609  without such implicit value conversion, use strictlyEquals().
610
611  Note that if this QScriptValue or the \a other value are objects,
612  calling this function has side effects on the script engine, since
613  the engine will call the object's valueOf() function (and possibly
614  toString()) in an attempt to convert the object to a primitive value
615  (possibly resulting in an uncaught script exception).
616
617  \sa strictlyEquals(), lessThan()
618*/
619bool QScriptValue::equals(const QScriptValue& other) const
620{
621    return d_ptr->equals(QScriptValuePrivate::get(other));
622}
623
624/*!
625  Returns true if this QScriptValue is equal to \a other using strict
626  comparison (no conversion), otherwise returns false. The comparison
627  follows the behavior described in \l{ECMA-262} section 11.9.6, "The
628  Strict Equality Comparison Algorithm".
629
630  If the type of this QScriptValue is different from the type of the
631  \a other value, this function returns false. If the types are equal,
632  the result depends on the type, as shown in the following table:
633
634    \table
635    \header \o Type \o Result
636    \row    \o Undefined  \o true
637    \row    \o Null       \o true
638    \row    \o Boolean    \o true if both values are true, false otherwise
639    \row    \o Number     \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
640    \row    \o String     \o true if both values are exactly the same sequence of characters, false otherwise
641    \row    \o Object     \o true if both values refer to the same object, false otherwise
642    \endtable
643
644  \sa equals()
645*/
646bool QScriptValue::strictlyEquals(const QScriptValue& other) const
647{
648    return d_ptr->strictlyEquals(QScriptValuePrivate::get(other));
649}
650
651/*!
652    Returns true if this QScriptValue is an instance of
653    \a other; otherwise returns false.
654
655    This QScriptValue is considered to be an instance of \a other if
656    \a other is a function and the value of the \c{prototype}
657    property of \a other is in the prototype chain of this
658    QScriptValue.
659*/
660bool QScriptValue::instanceOf(const QScriptValue& other) const
661{
662    return d_ptr->instanceOf(QScriptValuePrivate::get(other));
663}
664
665/*!
666  Returns the value of this QScriptValue's property with the given \a name,
667  using the given \a mode to resolve the property.
668
669  If no such property exists, an invalid QScriptValue is returned.
670
671  If the property is implemented using a getter function (i.e. has the
672  PropertyGetter flag set), calling property() has side-effects on the
673  script engine, since the getter function will be called (possibly
674  resulting in an uncaught script exception). If an exception
675  occurred, property() returns the value that was thrown (typically
676  an \c{Error} object).
677
678  \sa setProperty(), propertyFlags(), QScriptValueIterator
679*/
680QScriptValue QScriptValue::property(const QString& name, const ResolveFlags& mode) const
681{
682    return QScriptValuePrivate::get(d_ptr->property(name, mode));
683}
684
685/*!
686  \overload
687
688  Returns the value of this QScriptValue's property with the given \a name,
689  using the given \a mode to resolve the property.
690
691  This overload of property() is useful when you need to look up the
692  same property repeatedly, since the lookup can be performed faster
693  when the name is represented as an interned string.
694
695  \sa QScriptEngine::toStringHandle(), setProperty()
696*/
697QScriptValue QScriptValue::property(const QScriptString& name, const ResolveFlags& mode) const
698{
699    return QScriptValuePrivate::get(d_ptr->property(QScriptStringPrivate::get(name).constData(), mode));
700}
701
702/*!
703  \overload
704
705  Returns the property at the given \a arrayIndex, using the given \a
706  mode to resolve the property.
707
708  This function is provided for convenience and performance when
709  working with array objects.
710
711  If this QScriptValue is not an Array object, this function behaves
712  as if property() was called with the string representation of \a
713  arrayIndex.
714*/
715QScriptValue QScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode) const
716{
717    return QScriptValuePrivate::get(d_ptr->property(arrayIndex, mode));
718}
719
720/*!
721  Sets the value of this QScriptValue's property with the given \a name to
722  the given \a value.
723
724  If this QScriptValue is not an object, this function does nothing.
725
726  If this QScriptValue does not already have a property with name \a name,
727  a new property is created; the given \a flags then specify how this
728  property may be accessed by script code.
729
730  If \a value is invalid, the property is removed.
731
732  If the property is implemented using a setter function (i.e. has the
733  PropertySetter flag set), calling setProperty() has side-effects on
734  the script engine, since the setter function will be called with the
735  given \a value as argument (possibly resulting in an uncaught script
736  exception).
737
738  Note that you cannot specify custom getter or setter functions for
739  built-in properties, such as the \c{length} property of Array objects
740  or meta properties of QObject objects.
741
742  \sa property()
743*/
744void QScriptValue::setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags)
745{
746    d_ptr->setProperty(name, QScriptValuePrivate::get(value), flags);
747}
748
749/*!
750  \overload
751
752  Sets the property at the given \a arrayIndex to the given \a value.
753
754  This function is provided for convenience and performance when
755  working with array objects.
756
757  If this QScriptValue is not an Array object, this function behaves
758  as if setProperty() was called with the string representation of \a
759  arrayIndex.
760*/
761void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags)
762{
763    d_ptr->setProperty(arrayIndex, QScriptValuePrivate::get(value), flags);
764}
765
766/*!
767  Sets the value of this QScriptValue's property with the given \a
768  name to the given \a value. The given \a flags specify how this
769  property may be accessed by script code.
770
771  This overload of setProperty() is useful when you need to set the
772  same property repeatedly, since the operation can be performed
773  faster when the name is represented as an interned string.
774
775  \sa QScriptEngine::toStringHandle()
776*/
777void QScriptValue::setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags)
778{
779    d_ptr->setProperty(QScriptStringPrivate::get(name).constData(), QScriptValuePrivate::get(value), flags);
780}
781
782/*!
783  Returns the flags of the property with the given \a name, using the
784  given \a mode to resolve the property.
785
786  \sa property()
787*/
788QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString& name, const ResolveFlags& mode) const
789{
790    return d_ptr->propertyFlags(name, mode);
791}
792
793/*!
794  Returns the flags of the property with the given \a name, using the
795  given \a mode to resolve the property.
796
797  \sa property()
798*/
799QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString& name, const ResolveFlags& mode) const
800{
801    return d_ptr->propertyFlags(QScriptStringPrivate::get(name).constData(), mode);
802}
803