};
struct ForEachIteratorObject: Object {
- ExecutionContext *context;
ObjectIterator it;
ForEachIteratorObject(ExecutionContext *ctx, Object *o)
- : context(ctx), it(o, ObjectIterator::EnumberableOnly|ObjectIterator::WithProtoChain) {}
+ : it(ctx, o, ObjectIterator::EnumberableOnly|ObjectIterator::WithProtoChain) {}
virtual QString className() { return QStringLiteral("__ForEachIteratorObject"); }
- Value nextPropertyName() { return it.nextPropertyNameAsString(context); }
+ Value nextPropertyName() { return it.nextPropertyNameAsString(); }
protected:
virtual void getCollectables(QVector<Object *> &objects);
ArrayObject *array = ctx->engine->newArrayObject(ctx)->asArrayObject();
Array &a = array->array;
- ObjectIterator it(O, ObjectIterator::NoFlags);
+ ObjectIterator it(ctx, O, ObjectIterator::NoFlags);
while (1) {
- Value v = it.nextPropertyNameAsString(ctx);
+ Value v = it.nextPropertyNameAsString();
if (v.isNull())
break;
a.push_back(v);
Object *o = ctx->argument(1).toObject(ctx).objectValue();
- ObjectIterator it(o, ObjectIterator::EnumberableOnly);
+ ObjectIterator it(ctx, o, ObjectIterator::EnumberableOnly);
while (1) {
uint index;
String *name;
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
- ObjectIterator it(o, ObjectIterator::NoFlags);
+ ObjectIterator it(ctx, o, ObjectIterator::NoFlags);
while (1) {
uint index;
String *name;
Object *o = ctx->argument(0).objectValue();
o->extensible = false;
- ObjectIterator it(o, ObjectIterator::NoFlags);
+ ObjectIterator it(ctx, o, ObjectIterator::NoFlags);
while (1) {
uint index;
String *name;
if (o->extensible)
return Value::fromBoolean(false);
- ObjectIterator it(o, ObjectIterator::NoFlags);
+ ObjectIterator it(ctx, o, ObjectIterator::NoFlags);
while (1) {
uint index;
String *name;
if (o->extensible)
return Value::fromBoolean(false);
- ObjectIterator it(o, ObjectIterator::NoFlags);
+ ObjectIterator it(ctx, o, ObjectIterator::NoFlags);
while (1) {
uint index;
String *name;
ArrayObject *a = ctx->engine->newArrayObject(ctx);
- ObjectIterator it(o, ObjectIterator::EnumberableOnly);
+ ObjectIterator it(ctx, o, ObjectIterator::EnumberableOnly);
while (1) {
uint index;
String *name;
namespace QQmlJS {
namespace VM {
-ObjectIterator::ObjectIterator(Object *o, uint flags)
- : object(o)
+ObjectIterator::ObjectIterator(ExecutionContext *context, Object *o, uint flags)
+ : context(context)
+ , object(o)
, current(o)
, arrayNode(0)
, arrayIndex(0)
, tableIndex(0)
, flags(flags)
{
+ if (current && current->asStringObject())
+ this->flags |= CurrentIsString;
}
PropertyDescriptor *ObjectIterator::next(String **name, uint *index)
if (!current)
break;
+ if (flags & CurrentIsString) {
+ StringObject *s = static_cast<StringObject *>(current);
+ uint slen = s->value.stringValue()->toQString().length();
+ while (arrayIndex < slen) {
+ *index = arrayIndex;
+ ++arrayIndex;
+ return s->__getOwnProperty__(context, *index);
+ }
+ flags &= ~CurrentIsString;
+ arrayNode = current->array.sparseBegin();
+ // iterate until we're past the end of the string
+ while (arrayNode && arrayNode->key() < slen)
+ arrayNode = arrayNode->nextNode();
+ }
+
if (!arrayIndex)
arrayNode = current->array.sparseBegin();
while (arrayIndex < current->array.length()) {
p = current->array.at(arrayIndex);
++arrayIndex;
- if (p && (!(flags & EnumberableOnly) || p->isEnumerable())) {
+ if (p && p->type != PropertyDescriptor::Generic && (!(flags & EnumberableOnly) || p->isEnumerable())) {
*index = arrayIndex - 1;
return p;
}
current = current->prototype;
else
current = 0;
+ if (current && current->asStringObject())
+ flags |= CurrentIsString;
+ else
+ flags &= ~CurrentIsString;
+
+
arrayIndex = 0;
tableIndex = 0;
continue;
return Value::nullValue();
}
-Value ObjectIterator::nextPropertyNameAsString(ExecutionContext *context)
+Value ObjectIterator::nextPropertyNameAsString()
{
uint index;
String *name;
enum Flags {
NoFlags = 0,
EnumberableOnly = 0x1,
- WithProtoChain = 0x2
+ WithProtoChain = 0x2,
+ CurrentIsString = 0x4
};
+ ExecutionContext *context;
Object *object;
Object *current;
SparseArrayNode *arrayNode;
uint tableIndex;
uint flags;
- ObjectIterator(Object *o, uint flags);
+ ObjectIterator(ExecutionContext *context, Object *o, uint flags);
PropertyDescriptor *next(String **name, uint *index);
Value nextPropertyName();
- Value nextPropertyNameAsString(ExecutionContext *context);
+ Value nextPropertyNameAsString();
};
}