aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsapi/qjsvalue.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-12-20 12:31:52 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-01-12 10:49:10 +0100
commitc7722d4ed61d6a887e9f6c403ffa10b2048de2a4 (patch)
tree2d01090de983e4a354eb0359888aad0b78a26a08 /src/qml/jsapi/qjsvalue.cpp
parentc333d4108da6d3db06c17142226c28e14e89703f (diff)
Change value encoding scheme to make space for larger pointers
On android and on some other platforms, the upper bits of a pointer are significant. We need to store them in our JS value encoding. Shift the bits around to make this happen. We now can store pointers of up to 57 bits. That's enough for everything we've seen so far. Fixes: QTBUG-101686 Fixes: QTBUG-91150 Pick-to: 6.5 Change-Id: I72e0fe63b27fca94840f82963e4d3936b3581b28 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
Diffstat (limited to 'src/qml/jsapi/qjsvalue.cpp')
-rw-r--r--src/qml/jsapi/qjsvalue.cpp101
1 files changed, 64 insertions, 37 deletions
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 7306d00d6a..0aaa471e23 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -178,61 +178,59 @@ using namespace QV4;
/*!
Constructs a new QJSValue with a boolean \a value.
*/
-QJSValue::QJSValue(bool value) : d(QV4::Encode(value))
+QJSValue::QJSValue(bool value) : d(QJSValuePrivate::encode(value))
{
}
/*!
Constructs a new QJSValue with a number \a value.
*/
-QJSValue::QJSValue(int value) : d(QV4::Encode(value))
+QJSValue::QJSValue(int value) : d(QJSValuePrivate::encode(value))
{
}
/*!
Constructs a new QJSValue with a number \a value.
*/
-QJSValue::QJSValue(uint value) : d(QV4::Encode(value))
+QJSValue::QJSValue(uint value) : d(QJSValuePrivate::encode(value))
{
}
/*!
Constructs a new QJSValue with a number \a value.
*/
-QJSValue::QJSValue(double value) : d(QV4::Encode(value))
+QJSValue::QJSValue(double value) : d(QJSValuePrivate::encode(value))
{
}
/*!
Constructs a new QJSValue with a string \a value.
*/
-QJSValue::QJSValue(const QString& value)
+QJSValue::QJSValue(const QString &value) : d(QJSValuePrivate::encode(value))
{
- QJSValuePrivate::setString(this, QString(value));
}
/*!
Constructs a new QJSValue with a special \a value.
*/
-QJSValue::QJSValue(SpecialValue value) : d(value == NullValue ? QV4::Encode::null() : 0)
+QJSValue::QJSValue(SpecialValue value)
+ : d(value == NullValue ? QJSValuePrivate::encodeNull() : QJSValuePrivate::encodeUndefined())
{
}
/*!
Constructs a new QJSValue with a string \a value.
*/
-QJSValue::QJSValue(const QLatin1String &value)
+QJSValue::QJSValue(const QLatin1String &value) : d(QJSValuePrivate::encode(value))
{
- QJSValuePrivate::setString(this, QString(value));
}
/*!
Constructs a new QJSValue with a string \a value.
*/
#ifndef QT_NO_CAST_FROM_ASCII
-QJSValue::QJSValue(const char *value)
+QJSValue::QJSValue(const char *value) : d(QJSValuePrivate::encode(QString::fromUtf8(value)))
{
- QJSValuePrivate::setString(this, QString(QString::fromUtf8(value)));
}
#endif
@@ -243,12 +241,24 @@ QJSValue::QJSValue(const char *value)
true), then only a reference to the underlying object is copied into
the new script value (i.e., the object itself is not copied).
*/
-QJSValue::QJSValue(const QJSValue &other) : d(0)
+QJSValue::QJSValue(const QJSValue &other) : d(other.d)
{
- if (const QString *string = QJSValuePrivate::asQString(&other))
- QJSValuePrivate::setString(this, *string);
- else
- QJSValuePrivate::setValue(this, QJSValuePrivate::asReturnedValue(&other));
+ switch (QJSValuePrivate::tag(d)) {
+ case QJSValuePrivate::Kind::Undefined:
+ case QJSValuePrivate::Kind::Null:
+ case QJSValuePrivate::Kind::IntValue:
+ case QJSValuePrivate::Kind::BoolValue:
+ return;
+ case QJSValuePrivate::Kind::DoublePtr:
+ d = QJSValuePrivate::encode(*QJSValuePrivate::doublePtr(d));
+ return;
+ case QJSValuePrivate::Kind::QV4ValuePtr:
+ d = QJSValuePrivate::encode(*QJSValuePrivate::qv4ValuePtr(d));
+ return;
+ case QJSValuePrivate::Kind::QStringPtr:
+ d = QJSValuePrivate::encode(*QJSValuePrivate::qStringPtr(d));
+ break;
+ }
}
/*!
@@ -279,7 +289,7 @@ QJSValue::~QJSValue()
*/
bool QJSValue::isBool() const
{
- return QV4::Value::fromReturnedValue(d).isBoolean();
+ return QJSValuePrivate::tag(d) == QJSValuePrivate::Kind::BoolValue;
}
/*!
@@ -290,7 +300,15 @@ bool QJSValue::isBool() const
*/
bool QJSValue::isNumber() const
{
- return QV4::Value::fromReturnedValue(d).isNumber();
+ switch (QJSValuePrivate::tag(d)) {
+ case QJSValuePrivate::Kind::IntValue:
+ case QJSValuePrivate::Kind::DoublePtr:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
/*!
@@ -299,7 +317,7 @@ bool QJSValue::isNumber() const
*/
bool QJSValue::isNull() const
{
- return QV4::Value::fromReturnedValue(d).isNull();
+ return QJSValuePrivate::tag(d) == QJSValuePrivate::Kind::Null;
}
/*!
@@ -310,11 +328,17 @@ bool QJSValue::isNull() const
*/
bool QJSValue::isString() const
{
- if (QJSValuePrivate::asQString(this))
+ switch (QJSValuePrivate::tag(d)) {
+ case QJSValuePrivate::Kind::QStringPtr:
return true;
+ case QJSValuePrivate::Kind::QV4ValuePtr: {
+ return QJSValuePrivate::qv4ValuePtr(d)->isString();
+ }
+ default:
+ break;
+ }
- // String is managed
- return QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(this)).isString();
+ return false;
}
/*!
@@ -323,14 +347,16 @@ bool QJSValue::isString() const
*/
bool QJSValue::isUndefined() const
{
- if (QJSValuePrivate::asQString(this))
- return false;
- QV4::Value v = QV4::Value::fromReturnedValue(QJSValuePrivate::asReturnedValue(this));
- if (v.isUndefined())
+ switch (QJSValuePrivate::tag(d)) {
+ case QJSValuePrivate::Kind::Undefined:
return true;
- if (!v.isManaged())
- return false;
- return v.managed() == nullptr;
+ case QJSValuePrivate::Kind::QV4ValuePtr:
+ return QJSValuePrivate::qv4ValuePtr(d)->isUndefined();
+ default:
+ break;
+ }
+
+ return false;
}
/*!
@@ -867,22 +893,22 @@ QJSValue::QJSValue(QJSPrimitiveValue &&value)
{
switch (value.type()) {
case QJSPrimitiveValue::Undefined:
- d = QV4::Encode::undefined();
+ d = QJSValuePrivate::encodeUndefined();
return;
case QJSPrimitiveValue::Null:
- d = QV4::Encode::null();
+ d = QJSValuePrivate::encodeNull();
return;
case QJSPrimitiveValue::Boolean:
- d = QV4::Encode(value.asBoolean());
+ d = QJSValuePrivate::encode(value.asBoolean());
return;
case QJSPrimitiveValue::Integer:
- d = QV4::Encode(value.asInteger());
+ d = QJSValuePrivate::encode(value.asInteger());
return;
case QJSPrimitiveValue::Double:
- d = QV4::Encode(value.asDouble());
+ d = QJSValuePrivate::encode(value.asDouble());
return;
case QJSPrimitiveValue::String:
- QJSValuePrivate::setString(this, value.asString());
+ d = QJSValuePrivate::encode(value.asString());
return;
}
@@ -894,10 +920,11 @@ QJSValue::QJSValue(QJSManagedValue &&value)
if (!value.d) {
d = QV4::Encode::undefined();
} else if (value.d->isManaged()) {
- QJSValuePrivate::setRawValue(this, value.d);
+ // If it's managed, we can adopt the persistent value.
+ QJSValuePrivate::adoptPersistentValue(this, value.d);
value.d = nullptr;
} else {
- d = value.d->asReturnedValue();
+ d = QJSValuePrivate::encode(*value.d);
QV4::PersistentValueStorage::free(value.d);
value.d = nullptr;
}