1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtScript module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser
11 ** General Public License version 2.1 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.LGPL included in the
13 ** packaging of this file. Please review the following information to
14 ** ensure the GNU Lesser General Public License version 2.1 requirements
15 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** If you have questions regarding the use of this file, please contact
18 ** us via http://www.qt-project.org/.
22 ****************************************************************************/
28 // This file is not part of the Qt API. It exists purely as an
29 // implementation detail. This header file may change from version to
30 // version without notice, or even be removed.
35 #ifndef QJSVALUE_IMPL_P_H
36 #define QJSVALUE_IMPL_P_H
38 #include "qjsconverter_p.h"
39 #include "qjsvalue_p.h"
40 #include "qv8engine_p.h"
41 #include "qscriptisolate_p.h"
45 QJSValuePrivate* QJSValuePrivate::get(const QJSValue& q) { Q_ASSERT(q.d_ptr.data()); return q.d_ptr.data(); }
47 QJSValue QJSValuePrivate::get(const QJSValuePrivate* d)
50 return QJSValue(const_cast<QJSValuePrivate*>(d));
53 QJSValue QJSValuePrivate::get(QScriptPassPointer<QJSValuePrivate> d)
59 QJSValue QJSValuePrivate::get(QJSValuePrivate* d)
65 QJSValuePrivate::QJSValuePrivate(bool value)
66 : m_engine(0), m_state(CBool), u(value)
70 QJSValuePrivate::QJSValuePrivate(int value)
71 : m_engine(0), m_state(CNumber), u(value)
75 QJSValuePrivate::QJSValuePrivate(uint value)
76 : m_engine(0), m_state(CNumber), u(value)
80 QJSValuePrivate::QJSValuePrivate(double value)
81 : m_engine(0), m_state(CNumber), u(value)
85 QJSValuePrivate::QJSValuePrivate(const QString& value)
86 : m_engine(0), m_state(CString), u(new QString(value))
90 QJSValuePrivate::QJSValuePrivate(QJSValue::SpecialValue value)
91 : m_engine(0), m_state(value == QJSValue::NullValue ? CNull : CUndefined)
95 QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, bool value)
96 : m_engine(engine), m_state(JSValue)
99 v8::HandleScope handleScope;
100 m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
101 m_engine->registerValue(this);
104 QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, int value)
105 : m_engine(engine), m_state(JSValue)
108 v8::HandleScope handleScope;
109 m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
110 m_engine->registerValue(this);
113 QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, uint value)
114 : m_engine(engine), m_state(JSValue)
117 v8::HandleScope handleScope;
118 m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
119 m_engine->registerValue(this);
122 QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, double value)
123 : m_engine(engine), m_state(JSValue)
126 v8::HandleScope handleScope;
127 m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
128 m_engine->registerValue(this);
131 QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, const QString& value)
132 : m_engine(engine), m_state(JSValue)
135 v8::HandleScope handleScope;
136 m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
137 m_engine->registerValue(this);
140 QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, QJSValue::SpecialValue value)
141 : m_engine(engine), m_state(JSValue)
144 v8::HandleScope handleScope;
145 m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
146 m_engine->registerValue(this);
149 QJSValuePrivate::QJSValuePrivate(QV8Engine *engine, v8::Handle<v8::Value> value)
150 : m_engine(engine), m_state(JSValue), m_value(v8::Persistent<v8::Value>::New(value))
153 // It shouldn't happen, v8 shows errors by returning an empty handler. This is important debug
154 // information and it can't be simply ignored.
155 Q_ASSERT(!value.IsEmpty());
156 m_engine->registerValue(this);
159 QJSValuePrivate::~QJSValuePrivate()
162 m_engine->unregisterValue(this);
163 QScriptIsolate api(m_engine);
165 } else if (isStringBased()) {
170 bool QJSValuePrivate::toBool() const
175 v8::HandleScope scope;
176 return m_value->ToBoolean()->Value();
179 return !(qIsNaN(u.m_number) || !u.m_number);
186 return u.m_string->length();
189 Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
190 return false; // Avoid compiler warning.
193 double QJSValuePrivate::toNumber() const
198 v8::HandleScope scope;
199 return m_value->ToNumber()->Value();
204 return u.m_bool ? 1 : 0;
210 double result = u.m_string->toDouble(&ok);
213 result = u.m_string->toInt(&ok, 0); // Try other bases.
216 if (*u.m_string == QLatin1String("Infinity"))
218 if (*u.m_string == QLatin1String("-Infinity"))
220 return u.m_string->length() ? qQNaN() : 0;
223 Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
224 return 0; // Avoid compiler warning.
227 QString QJSValuePrivate::toString() const
231 return u.m_bool ? QString::fromLatin1("true") : QString::fromLatin1("false");
235 return QJSConverter::toString(u.m_number);
237 return QString::fromLatin1("null");
239 return QString::fromLatin1("undefined");
241 Q_ASSERT(!m_value.IsEmpty());
242 v8::HandleScope handleScope;
243 v8::TryCatch tryCatch;
244 v8::Local<v8::String> result = m_value->ToString();
245 if (result.IsEmpty()) {
246 result = tryCatch.Exception()->ToString();
247 m_engine->setException(tryCatch.Exception(), tryCatch.Message());
249 return QJSConverter::toString(result);
252 Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement.");
253 return QString(); // Avoid compiler warning.
256 QVariant QJSValuePrivate::toVariant() const
260 return QVariant(u.m_bool);
262 return QVariant(*u.m_string);
264 return QVariant(u.m_number);
273 Q_ASSERT(m_state == JSValue);
274 Q_ASSERT(!m_value.IsEmpty());
277 v8::HandleScope handleScope;
278 return m_engine->variantFromJS(m_value);
281 inline QDateTime QJSValuePrivate::toDataTime() const
286 v8::HandleScope handleScope;
287 return QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(m_value));
291 QObject* QJSValuePrivate::toQObject() const
296 v8::HandleScope handleScope;
297 return engine()->qtObjectFromJS(m_value);
300 double QJSValuePrivate::toInteger() const
302 double result = toNumber();
308 // Must use floor explicitly rather than qFloor here. On some
309 // platforms qFloor will cast the value to a single precision float and use
310 // floorf() which results in test failures.
311 return (result > 0) ? floor(result) : -1 * floor(-result);
314 qint32 QJSValuePrivate::toInt32() const
316 double result = toInteger();
317 // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
318 // some of these operation are invoked in toInteger subcall.
324 quint32 QJSValuePrivate::toUInt32() const
326 double result = toInteger();
327 // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
328 // some of these operation are invoked in toInteger subcall.
332 // The explicit casts are required to avoid undefined behaviour. For example, casting
333 // a negative double directly to an unsigned int on ARM NEON FPU results in the value
334 // being set to zero. Casting to a signed int first ensures well defined behaviour.
335 return (quint32) (qint32) result;
338 quint16 QJSValuePrivate::toUInt16() const
343 inline bool QJSValuePrivate::isArray() const
345 return isJSBased() && m_value->IsArray();
348 inline bool QJSValuePrivate::isBool() const
350 return m_state == CBool || (isJSBased() && m_value->IsBoolean());
353 inline bool QJSValuePrivate::isCallable() const
358 // Our C++ wrappers register function handlers but not always act as callables.
359 return v8::Object::Cast(*m_value)->IsCallable();
364 inline bool QJSValuePrivate::isError() const
368 v8::HandleScope handleScope;
369 return m_value->IsError();
372 inline bool QJSValuePrivate::isFunction() const
374 return isJSBased() && m_value->IsFunction();
377 inline bool QJSValuePrivate::isNull() const
379 return m_state == CNull || (isJSBased() && m_value->IsNull());
382 inline bool QJSValuePrivate::isNumber() const
384 return m_state == CNumber || (isJSBased() && m_value->IsNumber());
387 inline bool QJSValuePrivate::isObject() const
389 return isJSBased() && m_value->IsObject();
392 inline bool QJSValuePrivate::isString() const
394 return m_state == CString || (isJSBased() && m_value->IsString());
397 inline bool QJSValuePrivate::isUndefined() const
399 return m_state == CUndefined || (isJSBased() && m_value->IsUndefined());
402 inline bool QJSValuePrivate::isVariant() const
404 return isJSBased() && m_engine->isVariant(m_value);
407 bool QJSValuePrivate::isDate() const
409 return (isJSBased() && m_value->IsDate());
412 bool QJSValuePrivate::isRegExp() const
414 return (isJSBased() && m_value->IsRegExp());
417 bool QJSValuePrivate::isQObject() const
419 return isJSBased() && engine()->isQObject(m_value);
422 inline bool QJSValuePrivate::equals(QJSValuePrivate* other)
424 if (!isJSBased() && !other->isJSBased()) {
428 return other->isUndefined() || other->isNull();
430 switch (other->m_state) {
433 return u.m_number == other->toNumber();
435 return u.m_number == other->u.m_number;
440 switch (other->m_state) {
442 return u.m_bool == other->u.m_bool;
444 return toNumber() == other->u.m_number;
446 return toNumber() == other->toNumber();
451 switch (other->m_state) {
453 return toNumber() == other->toNumber();
455 return toNumber() == other->u.m_number;
457 return *u.m_string == *other->u.m_string;
462 Q_ASSERT_X(false, "QJSValue::equals", "Not all states are included in the previous switch statement.");
466 v8::HandleScope handleScope;
467 if (isJSBased() && !other->isJSBased()) {
468 if (!other->assignEngine(engine())) {
469 qWarning("QJSValue::equals: cannot compare to a value created in a different engine");
472 } else if (!isJSBased() && other->isJSBased()) {
473 if (!assignEngine(other->engine())) {
474 qWarning("QJSValue::equals: cannot compare to a value created in a different engine");
479 Q_ASSERT(this->engine() && other->engine());
480 if (this->engine() != other->engine()) {
481 qWarning("QJSValue::equals: cannot compare to a value created in a different engine");
484 return m_value->Equals(other->m_value);
487 inline bool QJSValuePrivate::strictlyEquals(QJSValuePrivate* other)
490 // We can't compare these two values without binding to the same engine.
491 if (!other->isJSBased()) {
492 if (other->assignEngine(engine()))
493 return m_value->StrictEquals(other->m_value);
496 if (other->engine() != engine()) {
497 qWarning("QJSValue::strictlyEquals: cannot compare to a value created in a different engine");
500 return m_value->StrictEquals(other->m_value);
502 if (isStringBased()) {
503 if (other->isStringBased())
504 return *u.m_string == *(other->u.m_string);
505 if (other->isJSBased()) {
506 assignEngine(other->engine());
507 return m_value->StrictEquals(other->m_value);
510 if (isNumberBased()) {
511 if (other->isJSBased()) {
512 assignEngine(other->engine());
513 return m_value->StrictEquals(other->m_value);
515 if (m_state != other->m_state)
517 if (m_state == CNumber)
518 return u.m_number == other->u.m_number;
519 Q_ASSERT(m_state == CBool);
520 return u.m_bool == other->u.m_bool;
523 return (isUndefined() && other->isUndefined())
524 || (isNull() && other->isNull());
527 inline bool QJSValuePrivate::lessThan(QJSValuePrivate *other) const
529 if (engine() != other->engine() && engine() && other->engine()) {
530 qWarning("QJSValue::lessThan: cannot compare to a value created in a different engine");
534 if (isString() && other->isString())
535 return toString() < other->toString();
537 if (isObject() || other->isObject()) {
538 v8::HandleScope handleScope;
539 QV8Engine *eng = m_engine ? engine() : other->engine();
540 // FIXME: lessThan can throw an exception which will be dropped by this code:
542 eng->saveException();
543 QScriptSharedDataPointer<QJSValuePrivate> cmp(eng->evaluate(QString::fromLatin1("(function(a,b){return a<b})")));
544 Q_ASSERT(cmp->isFunction());
545 v8::Handle<v8::Value> args[2];
546 cmp->prepareArgumentsForCall(args, QJSValueList() << QJSValuePrivate::get(this) << QJSValuePrivate::get(other));
547 QScriptSharedDataPointer<QJSValuePrivate> resultValue(cmp->call(0, 2, args));
548 bool result = resultValue->toBool();
549 eng->restoreException();
553 double nthis = toNumber();
554 double nother = other->toNumber();
555 if (qIsNaN(nthis) || qIsNaN(nother)) {
556 // Should return undefined in ECMA standard.
559 return nthis < nother;
562 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::prototype() const
565 v8::HandleScope handleScope;
566 return new QJSValuePrivate(engine(), v8::Handle<v8::Object>::Cast(m_value)->GetPrototype());
568 return new QJSValuePrivate();
571 inline void QJSValuePrivate::setPrototype(QJSValuePrivate* prototype)
573 if (isObject() && (prototype->isObject() || prototype->isNull())) {
574 if (engine() != prototype->engine()) {
575 if (prototype->engine()) {
576 qWarning("QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
579 prototype->assignEngine(engine());
581 v8::HandleScope handleScope;
582 if (!v8::Handle<v8::Object>::Cast(m_value)->SetPrototype(*prototype))
583 qWarning("QJSValue::setPrototype() failed: cyclic prototype value");
587 inline void QJSValuePrivate::setProperty(const QString& name, QJSValuePrivate* value, uint attribs)
591 v8::HandleScope handleScope;
592 setProperty(QJSConverter::toString(name), value, attribs);
595 inline void QJSValuePrivate::setProperty(v8::Handle<v8::String> name, QJSValuePrivate* value, uint attribs)
600 if (!value->isJSBased())
601 value->assignEngine(engine());
603 if (engine() != value->engine()) {
604 qWarning("QJSValue::setProperty(%s) failed: "
605 "cannot set value created in a different engine",
606 qPrintable(QJSConverter::toString(name)));
610 v8::TryCatch tryCatch;
611 // if (attribs & (QJSValue::PropertyGetter | QJSValue::PropertySetter)) {
612 // engine()->originalGlobalObject()->defineGetterOrSetter(*this, name, value->m_value, attribs);
614 v8::Object::Cast(*m_value)->Set(name, value->m_value, v8::PropertyAttribute(attribs & QJSConverter::PropertyAttributeMask));
616 if (tryCatch.HasCaught())
617 engine()->setException(tryCatch.Exception(), tryCatch.Message());
620 inline void QJSValuePrivate::setProperty(quint32 index, QJSValuePrivate* value, uint attribs)
622 // FIXME this method should by integrated with other overloads to use the same code patch.
623 // for now it is not possible as v8 doesn't allow to set property attributes using index based api.
629 // FIXME we dont need to convert index to a string.
630 //Object::Set(int,value) do not take attributes.
631 setProperty(QString::number(index), value, attribs);
635 if (!value->isJSBased())
636 value->assignEngine(engine());
638 if (engine() != value->engine()) {
639 qWarning("QJSValue::setProperty() failed: cannot set value created in a different engine");
643 v8::HandleScope handleScope;
644 v8::TryCatch tryCatch;
645 v8::Object::Cast(*m_value)->Set(index, value->m_value);
646 if (tryCatch.HasCaught())
647 engine()->setException(tryCatch.Exception(), tryCatch.Message());
650 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(const QString& name) const
653 return new QJSValuePrivate();
655 return new QJSValuePrivate(engine());
657 v8::HandleScope handleScope;
658 return property(QJSConverter::toString(name));
661 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(v8::Handle<v8::String> name) const
663 Q_ASSERT(!name.IsEmpty());
665 return new QJSValuePrivate();
666 return property<>(name);
669 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(quint32 index) const
672 return new QJSValuePrivate();
673 return property<>(index);
677 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(T name) const
679 Q_ASSERT(isObject());
680 v8::HandleScope handleScope;
681 v8::Handle<v8::Object> self(v8::Object::Cast(*m_value));
683 v8::TryCatch tryCatch;
684 v8::Handle<v8::Value> result = self->Get(name);
685 if (tryCatch.HasCaught()) {
686 result = tryCatch.Exception();
687 engine()->setException(result, tryCatch.Message());
688 return new QJSValuePrivate(engine(), result);
690 if (result.IsEmpty())
691 return new QJSValuePrivate(engine());
692 return new QJSValuePrivate(engine(), result);
695 inline bool QJSValuePrivate::deleteProperty(const QString& name)
700 v8::HandleScope handleScope;
701 v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value));
702 return self->Delete(QJSConverter::toString(name));
705 inline bool QJSValuePrivate::hasProperty(const QString &name) const
710 v8::HandleScope handleScope;
711 v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value));
712 return self->Has(QJSConverter::toString(name));
715 inline bool QJSValuePrivate::hasOwnProperty(const QString &name) const
720 v8::HandleScope handleScope;
721 v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value));
722 return self->HasOwnProperty(QJSConverter::toString(name));
725 inline QJSValuePrivate::PropertyFlags QJSValuePrivate::propertyFlags(const QString& name) const
728 return QJSValuePrivate::PropertyFlags(0);
730 v8::HandleScope handleScope;
731 return engine()->getPropertyFlags(v8::Handle<v8::Object>::Cast(m_value), QJSConverter::toString(name));
734 inline QJSValuePrivate::PropertyFlags QJSValuePrivate::propertyFlags(v8::Handle<v8::String> name) const
737 return QJSValuePrivate::PropertyFlags(0);
739 v8::HandleScope handleScope;
740 return engine()->getPropertyFlags(v8::Handle<v8::Object>::Cast(m_value), name);
743 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::call(QJSValuePrivate* thisObject, const QJSValueList& args)
746 return new QJSValuePrivate();
748 v8::HandleScope handleScope;
750 // Convert all arguments and bind to the engine.
751 int argc = args.size();
752 QVarLengthArray<v8::Handle<v8::Value>, 8> argv(argc);
753 if (!prepareArgumentsForCall(argv.data(), args)) {
754 qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
755 return new QJSValuePrivate(engine());
758 return call(thisObject, argc, argv.data());
761 QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::call(QJSValuePrivate* thisObject, int argc, v8::Handle<v8::Value> *argv)
763 QV8Engine *e = engine();
765 v8::Handle<v8::Object> recv;
767 if (!thisObject || !thisObject->isObject()) {
768 recv = v8::Handle<v8::Object>(v8::Object::Cast(*e->global()));
770 if (!thisObject->assignEngine(e)) {
771 qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine");
772 return new QJSValuePrivate(engine());
775 recv = v8::Handle<v8::Object>(v8::Object::Cast(*thisObject->m_value));
779 v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array"));
780 e->setException(exeption);
781 return new QJSValuePrivate(e, exeption);
784 v8::TryCatch tryCatch;
785 v8::Handle<v8::Value> result = v8::Object::Cast(*m_value)->CallAsFunction(recv, argc, argv);
787 if (result.IsEmpty()) {
788 result = tryCatch.Exception();
789 // TODO: figure out why v8 doesn't always produce an exception value.
790 //Q_ASSERT(!result.IsEmpty());
791 if (result.IsEmpty())
792 result = v8::Exception::Error(v8::String::New("missing exception value"));
793 e->setException(result, tryCatch.Message());
796 return new QJSValuePrivate(e, result);
799 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::callAsConstructor(int argc, v8::Handle<v8::Value> *argv)
801 QV8Engine *e = engine();
804 v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array"));
805 e->setException(exeption);
806 return new QJSValuePrivate(e, exeption);
809 v8::TryCatch tryCatch;
810 v8::Handle<v8::Value> result = v8::Object::Cast(*m_value)->CallAsConstructor(argc, argv);
812 if (result.IsEmpty()) {
813 result = tryCatch.Exception();
814 e->setException(result, tryCatch.Message());
817 return new QJSValuePrivate(e, result);
820 inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::callAsConstructor(const QJSValueList& args)
823 return new QJSValuePrivate();
825 v8::HandleScope handleScope;
827 // Convert all arguments and bind to the engine.
828 int argc = args.size();
829 QVarLengthArray<v8::Handle<v8::Value>, 8> argv(argc);
830 if (!prepareArgumentsForCall(argv.data(), args)) {
831 qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
832 return new QJSValuePrivate(engine());
835 return callAsConstructor(argc, argv.data());
839 * Make sure this value is associated with a v8 value belonging to this engine.
840 * If the value belongs to another engine, returns false.
842 bool QJSValuePrivate::assignEngine(QV8Engine* engine)
845 v8::HandleScope handleScope;
848 m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(u.m_bool));
851 m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(*u.m_string));
855 m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(u.m_number));
858 m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(QJSValue::NullValue));
861 m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(QJSValue::UndefinedValue));
864 if (this->engine() == engine)
866 else if (!isJSBased())
867 Q_ASSERT_X(!isJSBased(), "assignEngine()", "Not all states are included in the previous switch statement.");
869 qWarning("JSValue can't be rassigned to an another engine.");
875 m_engine->registerValue(this);
881 Invalidates this value (makes it undefined).
883 Does not remove the value from the engine's list of
884 registered values; that's the responsibility of the caller.
886 void QJSValuePrivate::invalidate()
891 } else if (isStringBased()) {
895 m_state = CUndefined;
898 QV8Engine* QJSValuePrivate::engine() const
903 inline QJSValuePrivate::operator v8::Handle<v8::Value>() const
905 Q_ASSERT(isJSBased());
909 inline QJSValuePrivate::operator v8::Handle<v8::Object>() const
911 Q_ASSERT(isObject());
912 return v8::Handle<v8::Object>::Cast(m_value);
916 * Return a v8::Handle, assign to the engine if needed.
918 v8::Handle<v8::Value> QJSValuePrivate::asV8Value(QV8Engine* engine)
921 if (!assignEngine(engine))
922 return v8::Handle<v8::Value>();
924 Q_ASSERT(isJSBased());
930 Returns true if QSV have an engine associated.
932 bool QJSValuePrivate::isJSBased() const
936 if (m_state >= JSValue)
937 Q_ASSERT(!m_value.IsEmpty());
939 Q_ASSERT(m_value.IsEmpty());
941 return m_state >= JSValue;
946 Returns true if current value of QSV is placed in m_number.
948 bool QJSValuePrivate::isNumberBased() const { return m_state == CNumber || m_state == CBool; }
952 Returns true if current value of QSV is placed in m_string.
954 bool QJSValuePrivate::isStringBased() const { return m_state == CString; }
958 Converts arguments and bind them to the engine.
959 \attention argv should be big enough
961 inline bool QJSValuePrivate::prepareArgumentsForCall(v8::Handle<v8::Value> argv[], const QJSValueList& args) const
963 QJSValueList::const_iterator i = args.constBegin();
964 for (int j = 0; i != args.constEnd(); j++, i++) {
965 QJSValuePrivate* value = QJSValuePrivate::get(*i);
966 if ((value->isJSBased() && engine() != value->engine())
967 || (!value->isJSBased() && !value->assignEngine(engine())))
968 // Different engines are not allowed!