251QJSValue::QJSValue(
const QJSValue &other) : d(other.d)
253 switch (QJSValuePrivate::tag(d)) {
254 case QJSValuePrivate::Kind::Undefined:
255 case QJSValuePrivate::Kind::Null:
256 case QJSValuePrivate::Kind::IntValue:
257 case QJSValuePrivate::Kind::BoolValue:
259 case QJSValuePrivate::Kind::DoublePtr:
260 d = QJSValuePrivate::encode(*QJSValuePrivate::doublePtr(d));
262 case QJSValuePrivate::Kind::QV4ValuePtr:
263 d = QJSValuePrivate::encode(*QJSValuePrivate::qv4ValuePtr(d));
265 case QJSValuePrivate::Kind::QStringPtr:
266 d = QJSValuePrivate::encode(*QJSValuePrivate::qStringPtr(d));
399QJSValue::ErrorType QJSValue::errorType()
const
401 const QV4::ErrorObject *error = QJSValuePrivate::asManagedType<ErrorObject>(
this);
404 switch (error->d()->errorType) {
405 case QV4::Heap::ErrorObject::Error:
407 case QV4::Heap::ErrorObject::EvalError:
409 case QV4::Heap::ErrorObject::RangeError:
411 case QV4::Heap::ErrorObject::ReferenceError:
412 return ReferenceError;
413 case QV4::Heap::ErrorObject::SyntaxError:
415 case QV4::Heap::ErrorObject::TypeError:
417 case QV4::Heap::ErrorObject::URIError:
420 Q_UNREACHABLE_RETURN(NoError);
601quint32 QJSValue::toUInt()
const
603 if (
const QString *string = QJSValuePrivate::asQString(
this))
604 return QV4::Value::toUInt32(RuntimeHelpers::stringToNumber(*string));
606 return caughtResult<quint32>(
this, &QV4::Value::toUInt32);
654QVariant QJSValue::toVariant(QJSValue::ObjectConversionBehavior behavior)
const
656 if (
const QString *string = QJSValuePrivate::asQString(
this))
657 return QVariant(*string);
659 QV4::Value val = QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(
this));
660 if (val.isUndefined())
663 return QVariant(QMetaType::fromType<std::nullptr_t>(),
nullptr);
665 return QVariant(val.booleanValue());
667 return QVariant(val.integerValue());
669 return QVariant(val.doubleValue());
671 Q_ASSERT(val.isManaged());
674 return QVariant(val.toQString());
676 if (behavior == RetainJSObjects) {
677 return QV4::ExecutionEngine::toVariant(
678 val, QMetaType{},
true);
680 return QV4::ExecutionEngine::toVariantLossy(val);
722QJSValue QJSValue::call(
const QJSValueList &args)
const
724 const FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(
this);
728 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
732 JSCallArguments jsCallData(scope, args.size());
733 *jsCallData.thisObject = engine->globalObject;
734 for (
int i = 0; i < args.size(); ++i) {
735 if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
736 qWarning(
"QJSValue::call() failed: cannot call function with argument created in a different engine");
739 jsCallData.args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i));
742 ScopedValue result(scope, f->call(jsCallData));
743 if (engine->hasException)
744 result = engine->catchException();
745 if (engine->isInterrupted.loadRelaxed())
746 result = engine->newErrorObject(QStringLiteral(
"Interrupted"));
748 return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
771QJSValue QJSValue::callWithInstance(
const QJSValue &instance,
const QJSValueList &args)
const
773 const FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(
this);
777 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
781 if (!QJSValuePrivate::checkEngine(engine, instance)) {
782 qWarning(
"QJSValue::call() failed: cannot call function with thisObject created in a different engine");
786 JSCallArguments jsCallData(scope, args.size());
787 *jsCallData.thisObject = QJSValuePrivate::convertToReturnedValue(engine, instance);
788 for (
int i = 0; i < args.size(); ++i) {
789 if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
790 qWarning(
"QJSValue::call() failed: cannot call function with argument created in a different engine");
793 jsCallData.args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i));
796 ScopedValue result(scope, f->call(jsCallData));
797 if (engine->hasException)
798 result = engine->catchException();
799 if (engine->isInterrupted.loadRelaxed())
800 result = engine->newErrorObject(QStringLiteral(
"Interrupted"));
802 return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
823QJSValue QJSValue::callAsConstructor(
const QJSValueList &args)
const
825 const FunctionObject *f = QJSValuePrivate::asManagedType<FunctionObject>(
this);
829 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
833 JSCallArguments jsCallData(scope, args.size());
834 for (
int i = 0; i < args.size(); ++i) {
835 if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
836 qWarning(
"QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
839 jsCallData.args[i] = QJSValuePrivate::convertToReturnedValue(engine, args.at(i));
842 ScopedValue result(scope, f->callAsConstructor(jsCallData));
843 if (engine->hasException)
844 result = engine->catchException();
845 if (engine->isInterrupted.loadRelaxed())
846 result = engine->newErrorObject(QStringLiteral(
"Interrupted"));
848 return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
858QJSValue QJSValue::prototype()
const
860 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
863 QV4::Scope scope(engine);
864 ScopedObject o(scope, QJSValuePrivate::asManagedType<QV4::Object>(
this));
867 ScopedObject p(scope, o->getPrototypeOf());
869 return QJSValue(NullValue);
870 return QJSValuePrivate::fromReturnedValue(p.asReturnedValue());
885void QJSValue::setPrototype(
const QJSValue& prototype)
887 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
891 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
894 QV4::Value val = QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(&prototype));
896 o->setPrototypeOf(
nullptr);
900 ScopedObject p(scope, val);
903 if (o->engine() != p->engine()) {
904 qWarning(
"QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
907 if (!o->setPrototypeOf(p))
908 qWarning(
"QJSValue::setPrototype() failed: cyclic prototype value");
918QJSValue& QJSValue::operator=(
const QJSValue& other)
923 QJSValuePrivate::free(
this);
926 if (
const QString *string = QJSValuePrivate::asQString(&other))
927 QJSValuePrivate::setString(
this, *string);
930 QJSValuePrivate::setValue(
932 QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(&other)));
937QJSValue::QJSValue(QJSPrimitiveValue &&value)
939 switch (value.type()) {
940 case QJSPrimitiveValue::Undefined:
941 d = QJSValuePrivate::encodeUndefined();
943 case QJSPrimitiveValue::Null:
944 d = QJSValuePrivate::encodeNull();
946 case QJSPrimitiveValue::Boolean:
947 d = QJSValuePrivate::encode(value.asBoolean());
949 case QJSPrimitiveValue::Integer:
950 d = QJSValuePrivate::encode(value.asInteger());
952 case QJSPrimitiveValue::Double:
953 d = QJSValuePrivate::encode(value.asDouble());
955 case QJSPrimitiveValue::String:
956 d = QJSValuePrivate::encode(value.asString());
963QJSValue::QJSValue(QJSManagedValue &&value)
966 d = QV4::Encode::undefined();
967 }
else if (value.d->isManaged()) {
969 QJSValuePrivate::adoptPersistentValue(
this, value.d);
972 d = QJSValuePrivate::encode(*value.d);
973 QV4::PersistentValueStorage::free(value.d);
978static bool js_equal(
const QString &string,
const QV4::Value &value)
980 if (String *s = value.stringValue())
981 return string == s->toQString();
982 if (value.isNumber())
983 return RuntimeHelpers::stringToNumber(string) == value.asDouble();
984 if (value.isBoolean())
985 return RuntimeHelpers::stringToNumber(string) ==
double(value.booleanValue());
986 if (QV4::Object *o = value.objectValue()) {
987 Scope scope(o->engine());
988 ScopedValue p(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT));
989 return js_equal(string, p);
1018bool QJSValue::equals(
const QJSValue& other)
const
1022 if (
const QString *string = QJSValuePrivate::asQString(
this)) {
1023 if (
const QString *otherString = QJSValuePrivate::asQString(&other))
1024 return *string == *otherString;
1025 return js_equal(*string, Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(&other)));
1028 if (
const QString *otherString = QJSValuePrivate::asQString(&other))
1029 return js_equal(*otherString, Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(
this)));
1031 return Runtime::CompareEqual::call(Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(
this)),
1032 Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(&other)));
1057bool QJSValue::strictlyEquals(
const QJSValue& other)
const
1059 if (
const QString *string = QJSValuePrivate::asQString(
this)) {
1060 if (
const QString *otherString = QJSValuePrivate::asQString(&other))
1061 return *string == *otherString;
1062 if (
const String *s = QJSValuePrivate::asManagedType<String>(&other))
1063 return *string == s->toQString();
1067 if (
const QString *otherString = QJSValuePrivate::asQString(&other)) {
1068 if (
const String *s = QJSValuePrivate::asManagedType<String>(
this))
1069 return *otherString == s->toQString();
1075 return RuntimeHelpers::strictEqual(Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(
this)),
1076 Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(&other)));
1096QJSValue QJSValue::property(
const QString& name)
const
1098 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1102 QV4::Scope scope(engine);
1103 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1107 ScopedString s(scope, engine->newString(name));
1108 QV4::ScopedValue result(scope, o->get(s->toPropertyKey()));
1109 if (engine->hasException)
1110 result = engine->catchException();
1112 return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
1144QJSValue QJSValue::property(quint32 arrayIndex)
const
1146 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1150 QV4::Scope scope(engine);
1151 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1155 QV4::ScopedValue result(scope, arrayIndex == UINT_MAX ? o->get(engine->id_uintMax()) : o->get(arrayIndex));
1156 if (engine->hasException)
1157 engine->catchException();
1158 return QJSValuePrivate::fromReturnedValue(result->asReturnedValue());
1176void QJSValue::setProperty(
const QString& name,
const QJSValue& value)
1178 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1181 Scope scope(engine);
1183 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1187 if (!QJSValuePrivate::checkEngine(engine, value)) {
1188 qWarning(
"QJSValue::setProperty(%s) failed: cannot set value created in a different engine", name.toUtf8().constData());
1192 ScopedString s(scope, engine->newString(name));
1193 QV4::ScopedValue v(scope, QJSValuePrivate::convertToReturnedValue(engine, value));
1194 o->put(s->toPropertyKey(), v);
1195 if (engine->hasException)
1196 engine->catchException();
1230void QJSValue::setProperty(quint32 arrayIndex,
const QJSValue& value)
1232 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1235 Scope scope(engine);
1237 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1241 if (!QJSValuePrivate::checkEngine(engine, value)) {
1242 qWarning(
"QJSValue::setProperty(%d) failed: cannot set value created in a different engine", arrayIndex);
1246 QV4::ScopedValue v(scope, QJSValuePrivate::convertToReturnedValue(engine, value));
1247 PropertyKey id = arrayIndex != UINT_MAX ? PropertyKey::fromArrayIndex(arrayIndex) : engine->id_uintMax()->propertyKey();
1249 if (engine->hasException)
1250 engine->catchException();
1273bool QJSValue::deleteProperty(
const QString &name)
1275 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1279 Scope scope(engine);
1280 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1284 ScopedString s(scope, engine->newString(name));
1285 return o->deleteProperty(s->toPropertyKey());
1294bool QJSValue::hasProperty(
const QString &name)
const
1296 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1300 Scope scope(engine);
1301 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1305 ScopedString s(scope, engine->newString(name));
1306 return o->hasProperty(s->toPropertyKey());
1315bool QJSValue::hasOwnProperty(
const QString &name)
const
1317 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1321 Scope scope(engine);
1322 ScopedObject o(scope, QJSValuePrivate::asReturnedValue(
this));
1326 ScopedString s(scope, engine->newIdentifier(name));
1327 return o->getOwnProperty(s->propertyKey()) != Attr_Invalid;
1340QObject *QJSValue::toQObject()
const
1342 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1345 QV4::Scope scope(engine);
1346 QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, QJSValuePrivate::asReturnedValue(
this));
1350 return wrapper->object();
1361const QMetaObject *QJSValue::toQMetaObject()
const
1363 QV4::ExecutionEngine *engine = QJSValuePrivate::engine(
this);
1366 QV4::Scope scope(engine);
1367 QV4::Scoped<QV4::QMetaObjectWrapper> wrapper(scope, QJSValuePrivate::asReturnedValue(
this));
1371 return wrapper->metaObject();
1437 quint32 isNullOrUndefined = 0;
1439 isNullOrUndefined |= 0x1;
1440 if (jsv.isUndefined())
1441 isNullOrUndefined |= 0x2;
1442 stream << isNullOrUndefined;
1443 if (!isNullOrUndefined) {
1444 const QVariant v = jsv.toVariant();
1445 switch (v.userType()) {
1446 case QMetaType::Bool:
1447 case QMetaType::Double:
1448 case QMetaType::Int:
1449 case QMetaType::QString:
1453 qWarning() <<
"QDataStream::operator<< was to save a non-trivial QJSValue."
1454 <<
"This is not supported anymore, please stream a QVariant instead.";
1455 QVariant().save(stream);
1465 quint32 isNullOrUndefined;
1466 stream >> isNullOrUndefined;
1468 if (isNullOrUndefined & 0x1) {
1469 jsv = QJSValue(QJSValue::NullValue);
1470 }
else if (isNullOrUndefined & 0x2) {
1476 switch (v.userType()) {
1477 case QMetaType::Bool:
1478 jsv = QJSValue(v.toBool());
1480 case QMetaType::Double:
1481 jsv = QJSValue(v.toDouble());
1483 case QMetaType::Int:
1484 jsv = QJSValue(v.toInt());
1486 case QMetaType::QString:
1487 jsv = QJSValue(v.toString());
1490 qWarning() <<
"QDataStream::operator>> to restore a non-trivial QJSValue."
1491 <<
"This is not supported anymore, please stream a QVariant instead.";