Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4variantobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
7#include <private/qqmlvaluetypewrapper_p.h>
8#include <private/qv4qobjectwrapper_p.h>
9
11
12using namespace QV4;
13
15
16void Heap::VariantObject::init()
17{
18 Object::init();
19 scarceData = new ExecutionEngine::ScarceResourceData;
20}
21
22void Heap::VariantObject::init(const QMetaType type, const void *data)
23{
24 Object::init();
25 scarceData = new ExecutionEngine::ScarceResourceData(type, data);
26 if (isScarce())
27 removeVmePropertyReference();
28}
29
30bool VariantObject::Data::isScarce() const
31{
32 int t = data().userType();
33 return t == QMetaType::QPixmap || t == QMetaType::QImage;
34}
35
36bool VariantObject::virtualIsEqualTo(Managed *m, Managed *other)
37{
38 Q_ASSERT(m->as<QV4::VariantObject>());
39 QV4::VariantObject *lv = static_cast<QV4::VariantObject *>(m);
40
41 if (QV4::VariantObject *rv = other->as<QV4::VariantObject>())
42 return lv->d()->data() == rv->d()->data();
43
44 if (QV4::QQmlValueTypeWrapper *v = other->as<QQmlValueTypeWrapper>())
45 return v->isEqual(lv->d()->data());
46
47 return false;
48}
49
50void VariantObject::addVmePropertyReference() const
51{
52 if (d()->isScarce() && ++d()->vmePropertyReferenceCount == 1) {
53 // remove from the ep->scarceResources list
54 // since it is now no longer eligible to be
55 // released automatically by the engine.
56 d()->addVmePropertyReference();
57 }
58}
59
60void VariantObject::removeVmePropertyReference() const
61{
62 if (d()->isScarce() && --d()->vmePropertyReferenceCount == 0) {
63 // and add to the ep->scarceResources list
64 // since it is now eligible to be released
65 // automatically by the engine.
66 d()->removeVmePropertyReference();
67 }
68}
69
70
71void VariantPrototype::init()
72{
73 defineDefaultProperty(QStringLiteral("preserve"), method_preserve, 0);
74 defineDefaultProperty(QStringLiteral("destroy"), method_destroy, 0);
75 defineDefaultProperty(engine()->id_valueOf(), method_valueOf, 0);
76 defineDefaultProperty(engine()->id_toString(), method_toString, 0);
77}
78
79ReturnedValue VariantPrototype::method_preserve(const FunctionObject *, const Value *thisObject, const Value *, int)
80{
81 const VariantObject *o = thisObject->as<QV4::VariantObject>();
82 if (o && o->d()->isScarce())
83 o->d()->addVmePropertyReference();
85}
86
87ReturnedValue VariantPrototype::method_destroy(const FunctionObject *, const Value *thisObject, const Value *, int)
88{
89 const VariantObject *o = thisObject->as<QV4::VariantObject>();
90 if (o) {
91 if (o->d()->isScarce())
92 o->d()->addVmePropertyReference();
93 o->d()->data() = QVariant();
94 }
96}
97
98ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
99{
100 ExecutionEngine *v4 = b->engine();
101 const VariantObject *o = thisObject->as<QV4::VariantObject>();
102 if (!o)
104 const QVariant variant = o->d()->data();
105 QString result = variant.toString();
106 if (result.isEmpty() && !variant.canConvert(QMetaType(QMetaType::QString))) {
107 QDebug dbg(&result);
108 dbg << variant;
109 // QDebug appends a space, we're not interested in continuing the stream so we chop it off.
110 // Can't use nospace() because it would affect the debug-stream operator of the variant.
111 result.chop(1);
112 }
113 return Encode(v4->newString(result));
114}
115
116ReturnedValue VariantPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
117{
118 const VariantObject *o = thisObject->as<QV4::VariantObject>();
119 if (o) {
120 QVariant v = o->d()->data();
121 switch (v.userType()) {
122 case QMetaType::UnknownType:
123 return Encode::undefined();
124 case QMetaType::QString:
125 return Encode(b->engine()->newString(v.toString()));
126 case QMetaType::Int:
127 return Encode(v.toInt());
128 case QMetaType::Double:
129 case QMetaType::UInt:
130 return Encode(v.toDouble());
131 case QMetaType::Bool:
132 return Encode(v.toBool());
133 default:
134 if (QMetaType(v.metaType()).flags() & QMetaType::IsEnumeration)
135 if (v.metaType().sizeOf() <= qsizetype(sizeof(int)))
136 return Encode(v.toInt());
137 if (v.canConvert<double>())
138 return Encode(v.toDouble());
139 if (v.canConvert<int>())
140 return Encode(v.toInt());
141 if (v.canConvert<uint>())
142 return Encode(v.toUInt());
143 if (v.canConvert<bool>())
144 return Encode(v.toBool());
145 if (v.canConvert<QString>())
146 return Encode(b->engine()->newString(v.toString()));
147 break;
148 }
149 }
150 return thisObject->asReturnedValue();
151}
152
153QT_END_NAMESPACE
#define RETURN_UNDEFINED()
DEFINE_OBJECT_VTABLE(VariantObject)