aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-10-13 14:39:47 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-10-13 14:40:30 +0200
commit042640042491106a2f5cbb6a93bbf8c0cade0b9d (patch)
tree259e412414fc86508b4c066a928d7b01c3d3a0b6 /src/qml/jsruntime
parent6df6c10e1af827d06a387e7422176dd310cf83be (diff)
parentf720242419cd73529277173e43e9f7a8ed367ad3 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.8
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp33
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp12
-rw-r--r--src/qml/jsruntime/qv4managed_p.h16
-rw-r--r--src/qml/jsruntime/qv4object_p.h12
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp24
-rw-r--r--src/qml/jsruntime/qv4value_p.h19
7 files changed, 82 insertions, 36 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 74c83b1940..bfeb3d4699 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -46,6 +46,8 @@
using namespace QV4;
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON
+
const QV4::VTable QV4::ArrayData::static_vtbl = {
0,
QV4::ArrayData::IsExecutionContext,
@@ -94,13 +96,15 @@ const ArrayVTable SparseArrayData::static_vtbl =
SparseArrayData::length
};
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
+
Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SimpleArrayData));
Q_STATIC_ASSERT(sizeof(Heap::ArrayData) == sizeof(Heap::SparseArrayData));
static Q_ALWAYS_INLINE void storeValue(ReturnedValue *target, uint value)
{
Value v;
- v.setTagValue(Value::fromReturnedValue(*target).tag(), value);
+ v.setEmpty(value);
*target = v.asReturnedValue();
}
@@ -189,6 +193,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
} else {
sparse->sparse = new SparseArray;
lastFree = &sparse->freeList;
+ storeValue(lastFree, 0);
for (uint i = 0; i < toCopy; ++i) {
if (!sparse->arrayData[i].isEmpty()) {
SparseArrayNode *n = sparse->sparse->insert(i);
@@ -209,6 +214,8 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
}
storeValue(lastFree, UINT_MAX);
}
+
+ Q_ASSERT(Value::fromReturnedValue(sparse->freeList).isEmpty());
// ### Could explicitly free the old data
}
@@ -357,12 +364,12 @@ void SparseArrayData::free(Heap::ArrayData *d, uint idx)
Value *v = d->arrayData + idx;
if (d->attrs && d->attrs[idx].isAccessor()) {
// double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
- v[1].setTagValue(Value::Empty_Type, Value::fromReturnedValue(d->freeList).value());
- v[0].setTagValue(Value::Empty_Type, idx + 1);
+ v[1].setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
+ v[0].setEmpty(idx + 1);
} else {
- v->setTagValue(Value::Empty_Type, Value::fromReturnedValue(d->freeList).value());
+ v->setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
}
- d->freeList = idx;
+ d->freeList = Primitive::emptyValue(idx).asReturnedValue();
if (d->attrs)
d->attrs[idx].clear();
}
@@ -400,9 +407,9 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
Q_ASSERT(dd->arrayData[Value::fromReturnedValue(*last).value()].value() != Value::fromReturnedValue(*last).value());
if (dd->arrayData[Value::fromReturnedValue(*last).value()].value() == (Value::fromReturnedValue(*last).value() + 1)) {
// found two slots in a row
- uint idx = Value::fromReturnedValue(*last).uint_32();
+ uint idx = Value::fromReturnedValue(*last).emptyValue();
Value lastV = Value::fromReturnedValue(*last);
- lastV.setTagValue(lastV.tag(), dd->arrayData[lastV.value() + 1].value());
+ lastV.setEmpty(dd->arrayData[lastV.emptyValue() + 1].value());
*last = lastV.rawValue();
dd->attrs[idx] = Attr_Accessor;
return idx;
@@ -416,7 +423,8 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
}
uint idx = Value::fromReturnedValue(dd->freeList).value();
Q_ASSERT(idx != UINT_MAX);
- dd->freeList = dd->arrayData[idx].uint_32();
+ dd->freeList = dd->arrayData[idx].asReturnedValue();
+ Q_ASSERT(Value::fromReturnedValue(dd->freeList).isEmpty());
if (dd->attrs)
dd->attrs[idx] = Attr_Data;
return idx;
@@ -471,13 +479,14 @@ bool SparseArrayData::del(Object *o, uint index)
if (isAccessor) {
// free up both indices
- dd->arrayData[pidx + 1].setTagValue(Value::Empty_Type, Value::fromReturnedValue(dd->freeList).value());
- dd->arrayData[pidx].setTagValue(Value::Undefined_Type, pidx + 1);
+ dd->arrayData[pidx + 1].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
+ dd->arrayData[pidx].setEmpty(pidx + 1);
} else {
- dd->arrayData[pidx].setTagValue(Value::Empty_Type, Value::fromReturnedValue(dd->freeList).value());
+ Q_ASSERT(dd->type == Heap::ArrayData::Sparse);
+ dd->arrayData[pidx].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
}
- dd->freeList = pidx;
+ dd->freeList = Primitive::emptyValue(pidx).asReturnedValue();
dd->sparse->erase(n);
return true;
}
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index bac45e18c8..d17da9af0c 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -132,16 +132,20 @@ static void insertHoleIntoPropertyData(Object *object, int idx)
int icSize = object->internalClass()->size;
int from = qMax(idx, inlineSize);
int to = from + 1;
- if (from < icSize)
- memmove(object->propertyData(to), object->propertyData(from), icSize - from - 1);
+ if (from < icSize) {
+ memmove(object->propertyData(to), object->propertyData(from),
+ (icSize - from - 1) * sizeof(Value));
+ }
if (from == idx)
return;
if (inlineSize < icSize)
*object->propertyData(inlineSize) = *object->propertyData(inlineSize - 1);
from = idx;
to = from + 1;
- if (from < inlineSize - 1)
- memmove(object->propertyData(to), object->propertyData(from), inlineSize - from - 1);
+ if (from < inlineSize - 1) {
+ memmove(object->propertyData(to), object->propertyData(from),
+ (inlineSize - from - 1) * sizeof(Value));
+ }
}
static void removeFromPropertyData(Object *object, int idx, bool accessor = false)
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 0359559f34..1fff5a45da 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -106,6 +106,18 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
#define Q_VTABLE_FUNCTION(classname, func) \
(classname::func == QV4::Managed::func ? 0 : classname::func)
+// Q_VTABLE_FUNCTION triggers a bogus tautological-compare warning in GCC6+
+#if defined(Q_CC_GNU) && Q_CC_GNU >= 600
+#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
+ QT_WARNING_PUSH; \
+ QT_WARNING_DISABLE_GCC("-Wtautological-compare")
+
+#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF \
+ ;QT_WARNING_POP
+#else
+#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON
+#define QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
+#endif
#define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \
{ \
@@ -125,7 +137,9 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
}
#define DEFINE_MANAGED_VTABLE(classname) \
-const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0)
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
+const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0) \
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
struct Q_QML_PRIVATE_EXPORT Managed : Value
{
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index e13a701b0f..d5195adaf0 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -144,7 +144,7 @@ struct ObjectVTable
void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
};
-#define DEFINE_OBJECT_VTABLE(classname) \
+#define DEFINE_OBJECT_VTABLE_BASE(classname) \
const QV4::ObjectVTable classname::static_vtbl = \
{ \
DEFINE_MANAGED_VTABLE_INT(classname, (QT_PREPEND_NAMESPACE(QtPrivate)::is_same<classname::SuperClass, Object>::value) ? Q_NULLPTR : &classname::SuperClass::static_vtbl.vTable), \
@@ -164,7 +164,15 @@ const QV4::ObjectVTable classname::static_vtbl = \
advanceIterator \
}
-
+#define DEFINE_OBJECT_VTABLE(classname) \
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
+DEFINE_OBJECT_VTABLE_BASE(classname) \
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
+
+#define DEFINE_OBJECT_TEMPLATE_VTABLE(classname) \
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
+template<> DEFINE_OBJECT_VTABLE_BASE(classname) \
+QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
struct Q_QML_EXPORT Object: Managed {
V4_OBJECT2(Object, Object)
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index 7ca0692804..a892194df3 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -139,7 +139,7 @@ PersistentValueStorage::Iterator &PersistentValueStorage::Iterator::operator++()
while (p) {
while (index < kEntriesPerPage - 1) {
++index;
- if (static_cast<Page *>(p)->values[index].tag() != QV4::Value::Empty_Type)
+ if (!static_cast<Page *>(p)->values[index].isEmpty())
return *this;
}
index = -1;
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 24890fdb18..3eb7772db7 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -601,29 +601,21 @@ typedef QQmlSequence<QVector<bool> > QQmlBoolVectorList;
template<>
DEFINE_OBJECT_VTABLE(QQmlBoolVectorList);
typedef QQmlSequence<QStringList> QQmlQStringList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlQStringList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQStringList);
typedef QQmlSequence<QList<QString> > QQmlStringList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlStringList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringList);
typedef QQmlSequence<QList<int> > QQmlIntList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlIntList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntList);
typedef QQmlSequence<QList<QUrl> > QQmlUrlList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlUrlList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlList);
typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlQModelIndexList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexList);
typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlQItemSelectionRangeList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQItemSelectionRangeList);
typedef QQmlSequence<QList<bool> > QQmlBoolList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlBoolList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolList);
typedef QQmlSequence<QList<qreal> > QQmlRealList;
-template<>
-DEFINE_OBJECT_VTABLE(QQmlRealList);
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealList);
}
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index b87dbc5b8d..4428c48d80 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -226,6 +226,17 @@ public:
setTagValue(Empty_Type_Internal, quint32(i));
}
+ Q_ALWAYS_INLINE void setEmpty(quint32 i)
+ {
+ setTagValue(Empty_Type_Internal, i);
+ }
+
+ Q_ALWAYS_INLINE quint32 emptyValue()
+ {
+ Q_ASSERT(isEmpty());
+ return quint32(value());
+ }
+
enum Type {
Undefined_Type,
Managed_Type,
@@ -536,6 +547,7 @@ ReturnedValue Heap::Base::asReturnedValue() const
struct Q_QML_PRIVATE_EXPORT Primitive : public Value
{
inline static Primitive emptyValue();
+ inline static Primitive emptyValue(uint v);
static inline Primitive fromBoolean(bool b);
static inline Primitive fromInt32(int i);
inline static Primitive undefinedValue();
@@ -565,6 +577,13 @@ inline Primitive Primitive::emptyValue()
return v;
}
+inline Primitive Primitive::emptyValue(uint e)
+{
+ Primitive v;
+ v.setEmpty(e);
+ return v;
+}
+
inline Primitive Primitive::nullValue()
{
Primitive v;