aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4referenceobject_p.h30
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp11
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h4
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp8
4 files changed, 45 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4referenceobject_p.h b/src/qml/jsruntime/qv4referenceobject_p.h
index 3dfea409db..61b8f02206 100644
--- a/src/qml/jsruntime/qv4referenceobject_p.h
+++ b/src/qml/jsruntime/qv4referenceobject_p.h
@@ -32,6 +32,7 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
NoFlag = 0,
CanWriteBack = 1 << 0,
IsVariant = 1 << 1,
+ EnforcesLocation = 1 << 2,
};
Q_DECLARE_FLAGS(Flags, Flag);
@@ -59,6 +60,33 @@ DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
void setIsVariant(bool isVariant) { setFlag(IsVariant, isVariant); }
bool isVariant() const { return hasFlag(IsVariant); }
+
+ void setEnforcesLocation(bool enforces) { setFlag(EnforcesLocation, enforces); }
+ bool enforcesLocation() const { return hasFlag(EnforcesLocation); }
+
+ void setLocation(const Function *function, quint16 statement)
+ {
+ m_function = function;
+ m_statementIndex = statement;
+ }
+
+ const Function *function() const { return m_function; }
+ quint16 statementIndex() const { return m_statementIndex; }
+
+ bool isAttachedToProperty() const
+ {
+ if (enforcesLocation()) {
+ if (CppStackFrame *frame = internalClass->engine->currentStackFrame) {
+ if (frame->v4Function != function() || frame->statementNumber() != statementIndex())
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool isReference() const { return m_property >= 0; }
private:
@@ -74,7 +102,9 @@ private:
}
QV4QPointer<QObject> m_object;
+ const Function *m_function;
int m_property;
+ quint16 m_statementIndex;
quint8 m_flags;
};
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 2558e376b5..6aadf68c05 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -162,6 +162,8 @@ void Heap::Sequence::init(
QV4::Scope scope(internalClass->engine);
QV4::Scoped<QV4::Sequence> o(scope, this);
o->setArrayType(Heap::ArrayData::Custom);
+ if (CppStackFrame *frame = scope.engine->currentStackFrame)
+ setLocation(frame->v4Function, frame->statementNumber());
o->loadReference();
}
@@ -422,18 +424,19 @@ bool Sequence::sort(const FunctionObject *f, const Value *, const Value *argv, i
void *Sequence::getRawContainerPtr() const
{ return d()->storagePointer(); }
-void Sequence::loadReference() const
+bool Sequence::loadReference() const
{
Q_ASSERT(d()->object());
Q_ASSERT(d()->isReference());
- QV4::ReferenceObject::readReference(d());
+ // If locations are enforced we only read once
+ return d()->enforcesLocation() || QV4::ReferenceObject::readReference(d());
}
-void Sequence::storeReference()
+bool Sequence::storeReference()
{
Q_ASSERT(d()->object());
Q_ASSERT(d()->isReference());
- QV4::ReferenceObject::writeBack(d());
+ return d()->isAttachedToProperty() && QV4::ReferenceObject::writeBack(d());
}
ReturnedValue Sequence::virtualGet(const Managed *that, PropertyKey id, const Value *receiver, bool *hasProperty)
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 6d0a85ded6..f6055e38e3 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -100,8 +100,8 @@ public:
bool containerIsEqualTo(Managed *other);
bool sort(const FunctionObject *f, const Value *, const Value *argv, int argc);
void *getRawContainerPtr() const;
- void loadReference() const;
- void storeReference();
+ bool loadReference() const;
+ bool storeReference();
};
}
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 2e7eaf23f8..721917bb6d 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -109,12 +109,13 @@ void *Heap::QQmlValueTypeWrapper::storagePointer()
bool Heap::QQmlValueTypeWrapper::readReference()
{
- return QV4::ReferenceObject::readReference(this);
+ // If locations are enforced we only read once
+ return enforcesLocation() || QV4::ReferenceObject::readReference(this);
}
bool Heap::QQmlValueTypeWrapper::writeBack()
{
- return QV4::ReferenceObject::writeBack(this);
+ return isAttachedToProperty() && QV4::ReferenceObject::writeBack(this);
}
ReturnedValue QQmlValueTypeWrapper::create(
@@ -130,6 +131,7 @@ ReturnedValue QQmlValueTypeWrapper::create(
r->d()->setMetaObject(cloneFrom->metaObject());
r->d()->setValueType(cloneFrom->valueType());
r->d()->setGadgetPtr(nullptr);
+ r->d()->setLocation(cloneFrom->function(), cloneFrom->statementIndex());
return r->asReturnedValue();
}
@@ -160,6 +162,8 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj
}
r->d()->setValueType(valueType);
r->d()->setGadgetPtr(nullptr);
+ if (CppStackFrame *frame = engine->currentStackFrame)
+ r->d()->setLocation(frame->v4Function, frame->statementNumber());
return r->asReturnedValue();
}