aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4objectiterator.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-09-30 13:48:05 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-02 16:07:33 +0200
commit430dfd326cb9d8dab8ebd11e83dd52e6d55c4229 (patch)
tree0d1dd82ddf8f027a591e93def6ce369237af725a /src/qml/jsruntime/qv4objectiterator.cpp
parent3dc090fc1eb0a810d96ffc87e4662f7eb9ac8fd2 (diff)
Fix ObjectIterator API to be GC safe
Change-Id: I3a9c48d53d8dbadcb9b32c00fcef1f89447c4b8c Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4objectiterator.cpp')
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp98
1 files changed, 75 insertions, 23 deletions
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index fc85a3f04c..2030489ea1 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -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);
+}