Fix ObjectIterator API to be GC safe
Change-Id: I3a9c48d53d8dbadcb9b32c00fcef1f89447c4b8c Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
parent
3dc090fc1e
commit
430dfd326c
|
@ -276,14 +276,13 @@ static ReturnedValue qmlsqldatabase_executeSql(SimpleCallContext *ctx)
|
|||
query.bindValue(ii, engine->toVariant((v = array->getIndexed(ii)), -1));
|
||||
} else if (values->asObject()) {
|
||||
ScopedObject object(scope, values);
|
||||
ObjectIterator it(object.getPointer(), ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
|
||||
ObjectIterator it(scope, object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
|
||||
ScopedValue key(scope);
|
||||
QV4::ScopedValue val(scope);
|
||||
while (1) {
|
||||
Value value;
|
||||
key = it.nextPropertyName(&value);
|
||||
key = it.nextPropertyName(val);
|
||||
if (key->isNull())
|
||||
break;
|
||||
QV4::ScopedValue val(scope, value);
|
||||
QVariant v = engine->toVariant(val, -1);
|
||||
if (key->isString()) {
|
||||
query.bindValue(key->stringValue()->toQString(), v);
|
||||
|
|
|
@ -50,12 +50,20 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
|
||||
: value(v)
|
||||
, iterator(QJSValuePrivate::get(v)->value.asObject(), QV4::ObjectIterator::NoFlags)
|
||||
, currentName(0)
|
||||
, currentIndex(UINT_MAX)
|
||||
, nextName(0)
|
||||
, nextIndex(UINT_MAX)
|
||||
{
|
||||
QJSValuePrivate *jsp = QJSValuePrivate::get(value);
|
||||
QV4::ExecutionEngine *e = jsp->engine;
|
||||
if (!e)
|
||||
return;
|
||||
|
||||
QV4::Scope scope(e);
|
||||
QV4::ScopedObject o(scope, jsp->value);
|
||||
iterator = e->newForEachIteratorObject(e->current, o)->asReturnedValue();
|
||||
|
||||
currentName = (QV4::String *)0;
|
||||
nextName = (QV4::String *)0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,7 +104,13 @@ QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
|
|||
QJSValueIterator::QJSValueIterator(const QJSValue& object)
|
||||
: d_ptr(new QJSValueIteratorPrivate(object))
|
||||
{
|
||||
d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
|
||||
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
|
||||
if (!v4)
|
||||
return;
|
||||
QV4::Scope scope(v4);
|
||||
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
|
||||
it->it.flags = QV4::ObjectIterator::NoFlags;
|
||||
it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -117,7 +131,7 @@ bool QJSValueIterator::hasNext() const
|
|||
{
|
||||
if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
|
||||
return false;
|
||||
return d_ptr->nextName != 0 || d_ptr->nextIndex != UINT_MAX;
|
||||
return !!d_ptr->nextName || d_ptr->nextIndex != UINT_MAX;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -139,8 +153,13 @@ bool QJSValueIterator::next()
|
|||
d_ptr->currentIndex = d_ptr->nextIndex;
|
||||
d_ptr->currentAttributes = d_ptr->nextAttributes;
|
||||
|
||||
d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
|
||||
return d_ptr->nextName != 0 || d_ptr->nextIndex != UINT_MAX;
|
||||
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
|
||||
if (!v4)
|
||||
return false;
|
||||
QV4::Scope scope(v4);
|
||||
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
|
||||
it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
|
||||
return !!d_ptr->nextName || d_ptr->nextIndex != UINT_MAX;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -153,7 +172,7 @@ QString QJSValueIterator::name() const
|
|||
{
|
||||
if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
|
||||
return QString();
|
||||
if (d_ptr->currentName)
|
||||
if (!!d_ptr->currentName)
|
||||
return d_ptr->currentName->toQString();
|
||||
if (d_ptr->currentIndex < UINT_MAX)
|
||||
return QString::number(d_ptr->currentIndex);
|
||||
|
@ -172,14 +191,18 @@ QJSValue QJSValueIterator::value() const
|
|||
if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
|
||||
return QJSValue();
|
||||
|
||||
QV4::Object *o = d_ptr->iterator.object;
|
||||
QV4::ExecutionEngine *engine = o->internalClass->engine;
|
||||
QV4::ExecutionEngine *engine = d_ptr->iterator.engine();
|
||||
if (!engine)
|
||||
return QJSValue();
|
||||
|
||||
QV4::Scope scope(engine);
|
||||
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
|
||||
QV4::ScopedObject o(scope, it->it.object);
|
||||
|
||||
QV4::ExecutionContext *ctx = engine->current;
|
||||
try {
|
||||
QV4::ScopedValue v(scope);
|
||||
if (d_ptr->currentName) {
|
||||
if (!!d_ptr->currentName) {
|
||||
QV4::ScopedString n(scope, d_ptr->currentName);
|
||||
v = o->get(n);
|
||||
} else if (d_ptr->currentIndex != UINT_MAX) {
|
||||
|
@ -202,8 +225,24 @@ QJSValue QJSValueIterator::value() const
|
|||
*/
|
||||
QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
|
||||
{
|
||||
d_ptr->iterator = QV4::ObjectIterator(QJSValuePrivate::get(object)->value.asObject(), QV4::ObjectIterator::NoFlags);
|
||||
d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
|
||||
d_ptr->value = object;
|
||||
d_ptr->currentIndex = UINT_MAX;
|
||||
d_ptr->nextIndex = UINT_MAX;
|
||||
d_ptr->currentName = (QV4::String *)0;
|
||||
d_ptr->nextName = (QV4::String *)0;
|
||||
QV4::ExecutionEngine *v4 = d_ptr->iterator.engine();
|
||||
if (!v4) {
|
||||
d_ptr->iterator = QV4::Encode::undefined();
|
||||
return *this;
|
||||
}
|
||||
|
||||
QJSValuePrivate *jsp = QJSValuePrivate::get(object);
|
||||
QV4::Scope scope(v4);
|
||||
QV4::ScopedObject o(scope, jsp->value);
|
||||
d_ptr->iterator = v4->newForEachIteratorObject(v4->current, o)->asReturnedValue();
|
||||
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
|
||||
it->it.flags = QV4::ObjectIterator::NoFlags;
|
||||
it->it.next(d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,12 +55,12 @@ public:
|
|||
QJSValueIteratorPrivate(const QJSValue &v);
|
||||
|
||||
QJSValue value;
|
||||
QV4::ObjectIterator iterator;
|
||||
QV4::PersistentValue iterator;
|
||||
QV4::PropertyAttributes currentAttributes;
|
||||
QV4::String *currentName;
|
||||
QV4::SafeString currentName;
|
||||
uint currentIndex;
|
||||
QV4::PropertyAttributes nextAttributes;
|
||||
QV4::String *nextName;
|
||||
QV4::SafeString nextName;
|
||||
uint nextIndex;
|
||||
};
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ static void realDumpValue(QV4::Value v, QV4::ExecutionContext *ctx, std::string
|
|||
return;
|
||||
}
|
||||
|
||||
Object *o = v.objectValue();
|
||||
ScopedObject o(scope, v);
|
||||
if (!o)
|
||||
return;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <qv4value_p.h>
|
||||
#include <qv4object_p.h>
|
||||
#include <qv4objectproto_p.h>
|
||||
#include <qv4objectiterator_p.h>
|
||||
#include <qv4arrayobject_p.h>
|
||||
#include <qv4booleanobject_p.h>
|
||||
#include <qv4globalobject_p.h>
|
||||
|
@ -535,7 +536,7 @@ Returned<Object> *ExecutionEngine::newVariantObject(const QVariant &v)
|
|||
return o->asReturned<Object>();
|
||||
}
|
||||
|
||||
Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o)
|
||||
Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
|
||||
{
|
||||
Object *obj = new (memoryManager) ForEachIteratorObject(ctx, o);
|
||||
return obj->asReturned<Object>();
|
||||
|
|
|
@ -301,7 +301,7 @@ struct Q_QML_EXPORT ExecutionEngine
|
|||
|
||||
Returned<Object> *newVariantObject(const QVariant &v);
|
||||
|
||||
Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, Object *o);
|
||||
Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o);
|
||||
|
||||
Returned<Object> *qmlContextObject() const;
|
||||
|
||||
|
|
|
@ -791,16 +791,14 @@ QString Stringify::JO(ObjectRef o)
|
|||
|
||||
QStringList partial;
|
||||
if (propertyList.isEmpty()) {
|
||||
ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly);
|
||||
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
|
||||
ScopedValue name(scope);
|
||||
|
||||
ScopedValue val(scope);
|
||||
while (1) {
|
||||
Value v;
|
||||
name = it.nextPropertyNameAsString(&v);
|
||||
name = it.nextPropertyNameAsString(val);
|
||||
if (name->isNull())
|
||||
break;
|
||||
val = v;
|
||||
QString key = name->toQStringNoThrow();
|
||||
QString member = makeMember(key, val);
|
||||
if (!member.isEmpty())
|
||||
|
@ -1024,16 +1022,14 @@ QJsonObject JsonObject::toJsonObject(ObjectRef o, V4ObjectSet &visitedObjects)
|
|||
|
||||
visitedObjects.insert(o);
|
||||
|
||||
ObjectIterator it(o, ObjectIterator::EnumerableOnly);
|
||||
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
|
||||
ScopedValue name(scope);
|
||||
QV4::ScopedValue val(scope);
|
||||
while (1) {
|
||||
Value v;
|
||||
name = it.nextPropertyNameAsString(&v);
|
||||
name = it.nextPropertyNameAsString(val);
|
||||
if (name->isNull())
|
||||
break;
|
||||
|
||||
QV4::ScopedValue val(scope, v);
|
||||
|
||||
QString key = name->toQStringNoThrow();
|
||||
if (!val->asFunctionObject())
|
||||
result.insert(key, toJsonValue(val, visitedObjects));
|
||||
|
|
|
@ -241,3 +241,8 @@ bool Managed::deleteProperty(const StringRef name)
|
|||
{
|
||||
return vtbl->deleteProperty(this, name);
|
||||
}
|
||||
|
||||
Property *Managed::advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes)
|
||||
{
|
||||
return vtbl->advanceIterator(this, it, name, index, attributes);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ struct ManagedVTable
|
|||
ReturnedValue (*getLookup)(Managed *m, Lookup *l);
|
||||
void (*setLookup)(Managed *m, Lookup *l, const ValueRef v);
|
||||
bool (*isEqualTo)(Managed *m, Managed *other);
|
||||
Property *(*advanceIterator)(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
|
||||
Property *(*advanceIterator)(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
|
||||
const char *className;
|
||||
};
|
||||
|
||||
|
@ -278,8 +278,7 @@ public:
|
|||
|
||||
bool isEqualTo(Managed *other)
|
||||
{ return vtbl->isEqualTo(this, other); }
|
||||
Property *advanceIterator(ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes)
|
||||
{ return vtbl->advanceIterator(this, it, name, index, attributes); }
|
||||
Property *advanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
|
||||
|
||||
static void destroy(Managed *that) { that->_data = 0; }
|
||||
static bool hasInstance(Managed *that, const ValueRef value);
|
||||
|
|
|
@ -544,10 +544,10 @@ void Object::setLookup(Managed *m, Lookup *l, const ValueRef value)
|
|||
l->setter = Lookup::setterInsert2;
|
||||
}
|
||||
|
||||
Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
|
||||
Property *Object::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
|
||||
{
|
||||
Object *o = static_cast<Object *>(m);
|
||||
*name = 0;
|
||||
name = (String *)0;
|
||||
*index = UINT_MAX;
|
||||
|
||||
if (!it->arrayIndex)
|
||||
|
@ -595,7 +595,7 @@ Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name,
|
|||
PropertyAttributes a = o->internalClass->propertyData[it->memberIndex];
|
||||
++it->memberIndex;
|
||||
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
|
||||
*name = n;
|
||||
name = n;
|
||||
if (attrs)
|
||||
*attrs = a;
|
||||
return p;
|
||||
|
@ -1435,14 +1435,3 @@ QStringList ArrayObject::toQStringList() const
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_MANAGED_VTABLE(ForEachIteratorObject);
|
||||
|
||||
void ForEachIteratorObject::markObjects(Managed *that)
|
||||
{
|
||||
ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
|
||||
Object::markObjects(that);
|
||||
if (o->it.object)
|
||||
o->it.object->mark();
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "qv4managed_p.h"
|
||||
#include "qv4property_p.h"
|
||||
#include "qv4internalclass_p.h"
|
||||
#include "qv4objectiterator_p.h"
|
||||
#include "qv4sparsearray_p.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
@ -314,7 +313,7 @@ protected:
|
|||
static bool deleteIndexedProperty(Managed *m, uint index);
|
||||
static ReturnedValue getLookup(Managed *m, Lookup *l);
|
||||
static void setLookup(Managed *m, Lookup *l, const ValueRef v);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
|
||||
|
||||
|
||||
private:
|
||||
|
@ -329,21 +328,6 @@ private:
|
|||
friend struct ObjectPrototype;
|
||||
};
|
||||
|
||||
struct ForEachIteratorObject: Object {
|
||||
Q_MANAGED
|
||||
ObjectIterator it;
|
||||
ForEachIteratorObject(ExecutionContext *ctx, Object *o)
|
||||
: Object(ctx->engine), it(o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
|
||||
vtbl = &static_vtbl;
|
||||
type = Type_ForeachIteratorObject;
|
||||
}
|
||||
|
||||
ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
|
||||
|
||||
protected:
|
||||
static void markObjects(Managed *that);
|
||||
};
|
||||
|
||||
struct BooleanObject: Object {
|
||||
SafeValue value;
|
||||
BooleanObject(ExecutionEngine *engine, const ValueRef val)
|
||||
|
|
|
@ -45,22 +45,40 @@
|
|||
|
||||
using namespace QV4;
|
||||
|
||||
ObjectIterator::ObjectIterator(Object *o, uint flags)
|
||||
: object(o)
|
||||
, current(o)
|
||||
ObjectIterator::ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags)
|
||||
: object(*scratch1)
|
||||
, current(*scratch2)
|
||||
, arrayNode(0)
|
||||
, arrayIndex(0)
|
||||
, memberIndex(0)
|
||||
, flags(flags)
|
||||
{
|
||||
object = o;
|
||||
current = o;
|
||||
tmpDynamicProperty.value = Primitive::undefinedValue();
|
||||
}
|
||||
|
||||
Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *attrs)
|
||||
ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
|
||||
: object(*static_cast<SafeObject *>(scope.alloc(1)))
|
||||
, current(*static_cast<SafeObject *>(scope.alloc(1)))
|
||||
, arrayNode(0)
|
||||
, arrayIndex(0)
|
||||
, memberIndex(0)
|
||||
, flags(flags)
|
||||
{
|
||||
Property *p = 0;
|
||||
*name = 0;
|
||||
object = o;
|
||||
current = o;
|
||||
tmpDynamicProperty.value = Primitive::undefinedValue();
|
||||
}
|
||||
|
||||
Property *ObjectIterator::next(StringRef name, uint *index, PropertyAttributes *attrs)
|
||||
{
|
||||
name = (String *)0;
|
||||
*index = UINT_MAX;
|
||||
if (!object)
|
||||
return 0;
|
||||
|
||||
Property *p = 0;
|
||||
while (1) {
|
||||
if (!current)
|
||||
break;
|
||||
|
@ -69,10 +87,8 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
|
|||
// check the property is not already defined earlier in the proto chain
|
||||
if (current != object) {
|
||||
Property *pp;
|
||||
if (*name) {
|
||||
Scope scope(object->engine());
|
||||
ScopedString n(scope, *name);
|
||||
pp = object->__getPropertyDescriptor__(n);
|
||||
if (name) {
|
||||
pp = object->__getPropertyDescriptor__(name);
|
||||
} else {
|
||||
assert (*index != UINT_MAX);
|
||||
pp = object->__getPropertyDescriptor__(*index);
|
||||
|
@ -86,7 +102,7 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
|
|||
if (flags & WithProtoChain)
|
||||
current = current->prototype();
|
||||
else
|
||||
current = 0;
|
||||
current = (Object *)0;
|
||||
|
||||
arrayIndex = 0;
|
||||
memberIndex = 0;
|
||||
|
@ -94,38 +110,74 @@ Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *a
|
|||
return 0;
|
||||
}
|
||||
|
||||
ReturnedValue ObjectIterator::nextPropertyName(Value *value)
|
||||
ReturnedValue ObjectIterator::nextPropertyName(ValueRef value)
|
||||
{
|
||||
if (!object)
|
||||
return Encode::null();
|
||||
|
||||
PropertyAttributes attrs;
|
||||
uint index;
|
||||
String *name;
|
||||
Property *p = next(&name, &index, &attrs);
|
||||
Scope scope(object->engine());
|
||||
ScopedString name(scope);
|
||||
Property *p = next(name, &index, &attrs);
|
||||
if (!p)
|
||||
return Encode::null();
|
||||
|
||||
if (value)
|
||||
*value = Value::fromReturnedValue(object->getValue(p, attrs));
|
||||
value = Value::fromReturnedValue(object->getValue(p, attrs));
|
||||
|
||||
if (name)
|
||||
if (!!name)
|
||||
return name->asReturnedValue();
|
||||
assert(index < UINT_MAX);
|
||||
return Encode(index);
|
||||
}
|
||||
|
||||
ReturnedValue ObjectIterator::nextPropertyNameAsString(Value *value)
|
||||
ReturnedValue ObjectIterator::nextPropertyNameAsString(ValueRef value)
|
||||
{
|
||||
if (!object)
|
||||
return Encode::null();
|
||||
|
||||
PropertyAttributes attrs;
|
||||
uint index;
|
||||
String *name;
|
||||
Property *p = next(&name, &index, &attrs);
|
||||
Scope scope(object->engine());
|
||||
ScopedString name(scope);
|
||||
Property *p = next(name, &index, &attrs);
|
||||
if (!p)
|
||||
return Encode::null();
|
||||
|
||||
if (value)
|
||||
*value = Value::fromReturnedValue(object->getValue(p, attrs));
|
||||
value = Value::fromReturnedValue(object->getValue(p, attrs));
|
||||
|
||||
if (name)
|
||||
if (!!name)
|
||||
return name->asReturnedValue();
|
||||
assert(index < UINT_MAX);
|
||||
return Encode(object->engine()->newString(QString::number(index)));
|
||||
}
|
||||
|
||||
ReturnedValue ObjectIterator::nextPropertyNameAsString()
|
||||
{
|
||||
if (!object)
|
||||
return Encode::null();
|
||||
|
||||
PropertyAttributes attrs;
|
||||
uint index;
|
||||
Scope scope(object->engine());
|
||||
ScopedString name(scope);
|
||||
Property *p = next(name, &index, &attrs);
|
||||
if (!p)
|
||||
return Encode::null();
|
||||
|
||||
if (!!name)
|
||||
return name->asReturnedValue();
|
||||
assert(index < UINT_MAX);
|
||||
return Encode(object->engine()->newString(QString::number(index)));
|
||||
}
|
||||
|
||||
|
||||
DEFINE_MANAGED_VTABLE(ForEachIteratorObject);
|
||||
|
||||
void ForEachIteratorObject::markObjects(Managed *that)
|
||||
{
|
||||
ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
|
||||
o->workArea[0].mark();
|
||||
o->workArea[1].mark();
|
||||
Object::markObjects(that);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#include "qv4global_p.h"
|
||||
#include "qv4property_p.h"
|
||||
#include "qv4scopedvalue_p.h"
|
||||
#include "qv4object_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -65,8 +67,8 @@ struct Q_QML_EXPORT ObjectIterator
|
|||
WithProtoChain = 0x2,
|
||||
};
|
||||
|
||||
Object *object;
|
||||
Object *current;
|
||||
ObjectRef object;
|
||||
ObjectRef current;
|
||||
SparseArrayNode *arrayNode;
|
||||
uint arrayIndex;
|
||||
uint memberIndex;
|
||||
|
@ -74,12 +76,32 @@ struct Q_QML_EXPORT ObjectIterator
|
|||
|
||||
Property tmpDynamicProperty;
|
||||
|
||||
ObjectIterator(Object *o, uint flags);
|
||||
Property *next(String **name, uint *index, PropertyAttributes *attributes = 0);
|
||||
ReturnedValue nextPropertyName(Value *value = 0);
|
||||
ReturnedValue nextPropertyNameAsString(Value *value = 0);
|
||||
ObjectIterator(SafeObject *scratch1, SafeObject *scratch2, const ObjectRef o, uint flags);
|
||||
ObjectIterator(Scope &scope, const ObjectRef o, uint flags);
|
||||
Property *next(StringRef name, uint *index, PropertyAttributes *attributes = 0);
|
||||
ReturnedValue nextPropertyName(ValueRef value);
|
||||
ReturnedValue nextPropertyNameAsString(ValueRef value);
|
||||
ReturnedValue nextPropertyNameAsString();
|
||||
};
|
||||
|
||||
struct ForEachIteratorObject: Object {
|
||||
Q_MANAGED
|
||||
ObjectIterator it;
|
||||
ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
|
||||
: Object(ctx->engine), it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
|
||||
vtbl = &static_vtbl;
|
||||
type = Type_ForeachIteratorObject;
|
||||
}
|
||||
|
||||
ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
|
||||
|
||||
protected:
|
||||
static void markObjects(Managed *that);
|
||||
|
||||
SafeObject workArea[2];
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -222,14 +222,12 @@ ReturnedValue ObjectPrototype::method_defineProperties(SimpleCallContext *ctx)
|
|||
Scoped<Object> o(scope, ctx->argument(1), Scoped<Object>::Convert);
|
||||
ScopedValue val(scope);
|
||||
|
||||
ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly);
|
||||
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
|
||||
ScopedString name(scope);
|
||||
while (1) {
|
||||
uint index;
|
||||
ScopedString name(scope);
|
||||
PropertyAttributes attrs;
|
||||
String *tmp = 0;
|
||||
Property *pd = it.next(&tmp, &index, &attrs);
|
||||
name = tmp;
|
||||
Property *pd = it.next(name, &index, &attrs);
|
||||
if (!pd)
|
||||
break;
|
||||
Property n;
|
||||
|
@ -375,7 +373,7 @@ ReturnedValue ObjectPrototype::method_keys(SimpleCallContext *ctx)
|
|||
|
||||
Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject());
|
||||
|
||||
ObjectIterator it(o.getPointer(), ObjectIterator::EnumerableOnly);
|
||||
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
|
||||
ScopedValue name(scope);
|
||||
while (1) {
|
||||
name = it.nextPropertyNameAsString();
|
||||
|
@ -652,7 +650,7 @@ Returned<ArrayObject> *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4,
|
|||
Scoped<ArrayObject> array(scope, v4->newArrayObject());
|
||||
ScopedObject O(scope, o);
|
||||
if (O) {
|
||||
ObjectIterator it(O.getPointer(), ObjectIterator::NoFlags);
|
||||
ObjectIterator it(scope, O, ObjectIterator::NoFlags);
|
||||
ScopedValue name(scope);
|
||||
while (1) {
|
||||
name = it.nextPropertyNameAsString();
|
||||
|
|
|
@ -646,13 +646,11 @@ PropertyAttributes QObjectWrapper::query(const Managed *m, StringRef name)
|
|||
return QV4::Object::query(m, name);
|
||||
}
|
||||
|
||||
Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes)
|
||||
Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes)
|
||||
{
|
||||
*name = 0;
|
||||
name = (String *)0;
|
||||
*index = UINT_MAX;
|
||||
|
||||
QV4::Scope scope(m->engine());
|
||||
|
||||
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
|
||||
|
||||
if (!that->m_object)
|
||||
|
@ -661,22 +659,20 @@ Property *QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String
|
|||
const QMetaObject *mo = that->m_object->metaObject();
|
||||
const int propertyCount = mo->propertyCount();
|
||||
if (it->arrayIndex < propertyCount) {
|
||||
ScopedString n(scope, that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name())));
|
||||
*name = n.getPointer();
|
||||
name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()));
|
||||
++it->arrayIndex;
|
||||
if (attributes)
|
||||
*attributes = QV4::Attr_Data;
|
||||
it->tmpDynamicProperty.value = that->get(n);
|
||||
it->tmpDynamicProperty.value = that->get(name);
|
||||
return &it->tmpDynamicProperty;
|
||||
}
|
||||
const int methodCount = mo->methodCount();
|
||||
if (it->arrayIndex < propertyCount + methodCount) {
|
||||
ScopedString n(scope, that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name())));
|
||||
*name = n.getPointer();
|
||||
name = that->engine()->newString(QString::fromUtf8(mo->method(it->arrayIndex - propertyCount).name()));
|
||||
++it->arrayIndex;
|
||||
if (attributes)
|
||||
*attributes = QV4::Attr_Data;
|
||||
it->tmpDynamicProperty.value = that->get(n);
|
||||
it->tmpDynamicProperty.value = that->get(name);
|
||||
return &it->tmpDynamicProperty;
|
||||
}
|
||||
return QV4::Object::advanceIterator(m, it, name, index, attributes);
|
||||
|
|
|
@ -108,7 +108,7 @@ private:
|
|||
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
|
||||
static void put(Managed *m, const StringRef name, const ValueRef value);
|
||||
static PropertyAttributes query(const Managed *, StringRef name);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
|
||||
static void markObjects(Managed *that);
|
||||
static void collectDeletables(Managed *m, GCDeletable **deletable);
|
||||
static void destroy(Managed *that)
|
||||
|
|
|
@ -174,7 +174,7 @@ bool RegExp::deleteIndexedProperty(Managed *m, uint index)
|
|||
return false;
|
||||
}
|
||||
|
||||
Property *RegExp::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes)
|
||||
Property *RegExp::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ protected:
|
|||
static PropertyAttributes queryIndexed(const Managed *m, uint index);
|
||||
static bool deleteProperty(Managed *, const StringRef);
|
||||
static bool deleteIndexedProperty(Managed *m, uint index);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
|
||||
|
||||
private:
|
||||
friend class RegExpCache;
|
||||
|
|
|
@ -544,7 +544,7 @@ ReturnedValue __qmljs_foreach_iterator_object(ExecutionContext *ctx, const Value
|
|||
Scoped<Object> o(scope, (Object *)0);
|
||||
if (!in->isNullOrUndefined())
|
||||
o = in;
|
||||
Scoped<Object> it(scope, ctx->engine->newForEachIteratorObject(ctx, o.getPointer()));
|
||||
Scoped<Object> it(scope, ctx->engine->newForEachIteratorObject(ctx, o));
|
||||
return it.asReturnedValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -463,9 +463,18 @@ struct Referenced {
|
|||
Referenced &operator=(const Referenced &o)
|
||||
{ *ptr = *o.ptr; return *this; }
|
||||
Referenced &operator=(T *t)
|
||||
{ ptr->val = t->asReturnedValue(); return *this; }
|
||||
Referenced &operator=(const Returned<T> *t) {
|
||||
ptr->val = t->getPointer()->asReturnedValue();
|
||||
{
|
||||
#if QT_POINTER_SIZE == 4
|
||||
ptr->tag = Value::Managed_Type;
|
||||
#endif
|
||||
ptr->m = t;
|
||||
return *this;
|
||||
}
|
||||
Referenced &operator=(Returned<T> *t) {
|
||||
#if QT_POINTER_SIZE == 4
|
||||
ptr->tag = Value::Managed_Type;
|
||||
#endif
|
||||
ptr->m = t->getPointer();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -277,9 +277,9 @@ public:
|
|||
return (signedIdx < m_container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
|
||||
}
|
||||
|
||||
Property *containerAdvanceIterator(ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
|
||||
Property *containerAdvanceIterator(ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
|
||||
{
|
||||
*name = 0;
|
||||
name = (String *)0;
|
||||
*index = UINT_MAX;
|
||||
|
||||
if (m_isReference) {
|
||||
|
@ -500,7 +500,7 @@ private:
|
|||
{ return static_cast<QQmlSequence<Container> *>(that)->containerDeleteIndexedProperty(index); }
|
||||
static bool isEqualTo(Managed *that, Managed *other)
|
||||
{ return static_cast<QQmlSequence<Container> *>(that)->containerIsEqualTo(other); }
|
||||
static Property *advanceIterator(Managed *that, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
|
||||
static Property *advanceIterator(Managed *that, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
|
||||
{ return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, attrs); }
|
||||
|
||||
static void destroy(Managed *that)
|
||||
|
|
|
@ -127,8 +127,9 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
|
|||
return true;
|
||||
}
|
||||
|
||||
Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
|
||||
Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
|
||||
{
|
||||
name = (String *)0;
|
||||
StringObject *s = static_cast<StringObject *>(m);
|
||||
uint slen = s->value.stringValue()->toQString().length();
|
||||
if (it->arrayIndex < slen) {
|
||||
|
|
|
@ -62,7 +62,7 @@ struct StringObject: Object {
|
|||
|
||||
protected:
|
||||
StringObject(InternalClass *ic);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs);
|
||||
static void markObjects(Managed *that);
|
||||
};
|
||||
|
||||
|
|
|
@ -386,6 +386,8 @@ struct Safe : public SafeValue
|
|||
|
||||
Safe &operator =(const Safe<T> &t);
|
||||
|
||||
bool operator!() const { return !managed(); }
|
||||
|
||||
// ### GC: remove me
|
||||
operator T*() { return static_cast<T *>(managed()); }
|
||||
Value *operator->() { return this; }
|
||||
|
|
|
@ -147,9 +147,9 @@ void QmlListWrapper::destroy(Managed *that)
|
|||
w->~QmlListWrapper();
|
||||
}
|
||||
|
||||
Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
|
||||
Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs)
|
||||
{
|
||||
*name = 0;
|
||||
name = (String *)0;
|
||||
*index = UINT_MAX;
|
||||
QmlListWrapper *w = m->as<QmlListWrapper>();
|
||||
quint32 count = w->property.count ? w->property.count(&w->property) : 0;
|
||||
|
|
|
@ -84,7 +84,7 @@ public:
|
|||
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
|
||||
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
|
||||
static void put(Managed *m, const StringRef name, const ValueRef value);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
|
||||
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
|
||||
static void destroy(Managed *that);
|
||||
|
||||
private:
|
||||
|
|
|
@ -613,16 +613,15 @@ QVariantMap QV8Engine::variantMapFromJS(QV4::ObjectRef o,
|
|||
|
||||
visitedObjects.insert(o);
|
||||
|
||||
QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly);
|
||||
QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
|
||||
QV4::ScopedValue name(scope);
|
||||
QV4::ScopedValue val(scope);
|
||||
while (1) {
|
||||
QV4::Value v;
|
||||
name = it.nextPropertyNameAsString(&v);
|
||||
name = it.nextPropertyNameAsString(val);
|
||||
if (name->isNull())
|
||||
break;
|
||||
|
||||
QString key = name->toQStringNoThrow();
|
||||
QV4::ScopedValue val(scope, v);
|
||||
result.insert(key, variantFromJS(val, visitedObjects));
|
||||
}
|
||||
|
||||
|
|
|
@ -1557,14 +1557,13 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
|
|||
if (!o)
|
||||
return false;
|
||||
|
||||
QV4::ObjectIterator it(o.getPointer(), QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain);
|
||||
QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly|QV4::ObjectIterator::WithProtoChain);
|
||||
QV4::ScopedValue propertyName(scope);
|
||||
QV4::ScopedValue v(scope);
|
||||
while (1) {
|
||||
QV4::Value value;
|
||||
propertyName = it.nextPropertyNameAsString(&value);
|
||||
propertyName = it.nextPropertyNameAsString(v);
|
||||
if (propertyName->isNull())
|
||||
break;
|
||||
QV4::ScopedValue v(scope, value);
|
||||
cacheItem->setValue(propertyName->toQStringNoThrow(), m_cacheMetaType->v8Engine->toVariant(v, QVariant::Invalid));
|
||||
}
|
||||
|
||||
|
|
|
@ -415,13 +415,13 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QVector<int> *roles
|
|||
|
||||
QV4::ExecutionEngine *v4 = object->engine();
|
||||
QV4::Scope scope(v4);
|
||||
QV4::Scoped<QV4::Object> o(scope);
|
||||
QV4::ScopedObject o(scope);
|
||||
|
||||
QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
|
||||
QV4::ObjectIterator it(scope, object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
|
||||
QV4::Scoped<QV4::String> propertyName(scope);
|
||||
QV4::ScopedValue propertyValue(scope);
|
||||
while (1) {
|
||||
QV4::Value propertyValue;
|
||||
propertyName = it.nextPropertyNameAsString(&propertyValue);
|
||||
propertyName = it.nextPropertyNameAsString(propertyValue);
|
||||
if (!propertyName)
|
||||
break;
|
||||
|
||||
|
@ -429,13 +429,13 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QVector<int> *roles
|
|||
int roleIndex = -1;
|
||||
|
||||
// Add the value now
|
||||
if (QV4::String *s = propertyValue.asString()) {
|
||||
if (QV4::String *s = propertyValue->asString()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String);
|
||||
roleIndex = e->setStringProperty(r, s->toQString());
|
||||
} else if (propertyValue.isNumber()) {
|
||||
} else if (propertyValue->isNumber()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number);
|
||||
roleIndex = e->setDoubleProperty(r, propertyValue.asDouble());
|
||||
} else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) {
|
||||
roleIndex = e->setDoubleProperty(r, propertyValue->asDouble());
|
||||
} else if (QV4::ArrayObject *a = propertyValue->asArrayObject()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List);
|
||||
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
|
||||
|
||||
|
@ -446,14 +446,14 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QVector<int> *roles
|
|||
}
|
||||
|
||||
roleIndex = e->setListProperty(r, subModel);
|
||||
} else if (propertyValue.isBoolean()) {
|
||||
} else if (propertyValue->isBoolean()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool);
|
||||
roleIndex = e->setBoolProperty(r, propertyValue.booleanValue());
|
||||
} else if (QV4::DateObject *dd = propertyValue.asDateObject()) {
|
||||
roleIndex = e->setBoolProperty(r, propertyValue->booleanValue());
|
||||
} else if (QV4::DateObject *dd = propertyValue->asDateObject()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime);
|
||||
QDateTime dt = dd->toQDateTime();
|
||||
roleIndex = e->setDateTimeProperty(r, dt);
|
||||
} else if (QV4::Object *o = propertyValue.asObject()) {
|
||||
} else if (QV4::Object *o = propertyValue->asObject()) {
|
||||
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
|
||||
QObject *o = wrapper->object();
|
||||
const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::QObject);
|
||||
|
@ -466,7 +466,7 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QVector<int> *roles
|
|||
roleIndex = e->setVariantMapProperty(role, obj, eng);
|
||||
}
|
||||
}
|
||||
} else if (propertyValue.isNullOrUndefined()) {
|
||||
} else if (propertyValue->isNullOrUndefined()) {
|
||||
const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer());
|
||||
if (r)
|
||||
e->clearProperty(*r);
|
||||
|
@ -489,25 +489,25 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
|
|||
QV4::Scope scope(v4);
|
||||
QV4::Scoped<QV4::Object> o(scope);
|
||||
|
||||
QV4::ObjectIterator it(object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
|
||||
QV4::ObjectIterator it(scope, object, QV4::ObjectIterator::WithProtoChain|QV4::ObjectIterator::EnumerableOnly);
|
||||
QV4::Scoped<QV4::String> propertyName(scope);
|
||||
QV4::ScopedValue propertyValue(scope);
|
||||
while (1) {
|
||||
QV4::Value propertyValue;
|
||||
propertyName = it.nextPropertyNameAsString(&propertyValue);
|
||||
propertyName = it.nextPropertyNameAsString(propertyValue);
|
||||
if (!propertyName)
|
||||
break;
|
||||
|
||||
// Add the value now
|
||||
if (QV4::String *s = propertyValue.asString()) {
|
||||
if (QV4::String *s = propertyValue->asString()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::String);
|
||||
if (r.type == ListLayout::Role::String)
|
||||
e->setStringPropertyFast(r, s->toQString());
|
||||
} else if (propertyValue.isNumber()) {
|
||||
} else if (propertyValue->isNumber()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Number);
|
||||
if (r.type == ListLayout::Role::Number) {
|
||||
e->setDoublePropertyFast(r, propertyValue.asDouble());
|
||||
e->setDoublePropertyFast(r, propertyValue->asDouble());
|
||||
}
|
||||
} else if (QV4::ArrayObject *a = propertyValue.asArrayObject()) {
|
||||
} else if (QV4::ArrayObject *a = propertyValue->asArrayObject()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::List);
|
||||
if (r.type == ListLayout::Role::List) {
|
||||
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
|
||||
|
@ -520,18 +520,18 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
|
|||
|
||||
e->setListPropertyFast(r, subModel);
|
||||
}
|
||||
} else if (propertyValue.isBoolean()) {
|
||||
} else if (propertyValue->isBoolean()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::Bool);
|
||||
if (r.type == ListLayout::Role::Bool) {
|
||||
e->setBoolPropertyFast(r, propertyValue.booleanValue());
|
||||
e->setBoolPropertyFast(r, propertyValue->booleanValue());
|
||||
}
|
||||
} else if (QV4::DateObject *dd = propertyValue.asDateObject()) {
|
||||
} else if (QV4::DateObject *dd = propertyValue->asDateObject()) {
|
||||
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName.getPointer(), ListLayout::Role::DateTime);
|
||||
if (r.type == ListLayout::Role::DateTime) {
|
||||
QDateTime dt = dd->toQDateTime();;
|
||||
e->setDateTimePropertyFast(r, dt);
|
||||
}
|
||||
} else if (propertyValue.isObject()) {
|
||||
} else if (propertyValue->isObject()) {
|
||||
QV4::ScopedObject o(scope, propertyValue);
|
||||
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
|
||||
QObject *o = wrapper->object();
|
||||
|
@ -543,7 +543,7 @@ void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
|
|||
if (role.type == ListLayout::Role::VariantMap)
|
||||
e->setVariantMapFast(role, o, eng);
|
||||
}
|
||||
} else if (propertyValue.isUndefined() || propertyValue.isNull()) {
|
||||
} else if (propertyValue->isNullOrUndefined()) {
|
||||
const ListLayout::Role *r = m_layout->getExistingRole(propertyName.getPointer());
|
||||
if (r)
|
||||
e->clearProperty(*r);
|
||||
|
|
Loading…
Reference in New Issue