return Value::fromUInt32(count);
}
+ uint idx = name->asArrayIndex();
+ if (idx != UINT_MAX)
+ return getIndexed(m, ctx, idx, hasProperty);
+
return Value::undefinedValue();
}
w->~QmlListWrapper();
}
-#if 0
-// ### does this need porting?
-v8::Handle<v8::Array> QV8ListWrapper::Enumerator(const v8::AccessorInfo &info)
+Property *QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
{
- QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This());
-
- if (!resource || resource->object.isNull()) return v8::Array::New();
-
- quint32 count = resource->property.count?resource->property.count(&resource->property):0;
-
- v8::Handle<v8::Array> rv = v8::Array::New(count);
-
- for (uint ii = 0; ii < count; ++ii)
- rv->Set(ii, Value::fromDouble(ii));
-
- return rv;
+ *name = 0;
+ *index = UINT_MAX;
+ QmlListWrapper *w = m->as<QmlListWrapper>();
+ quint32 count = w->property.count ? w->property.count(&w->property) : 0;
+ if (it->arrayIndex < count) {
+ if (attrs)
+ *attrs = QV4::Attr_Data;
+ *index = it->arrayIndex;
+ ++it->arrayIndex;
+ it->tmpDynamicProperty.value = QV4::QObjectWrapper::wrap(w->engine(), w->property.at(&w->property, *index));
+ return &it->tmpDynamicProperty;
+ }
+ return QV4::Object::advanceIterator(m, it, name, index, attrs);
}
-#endif
QT_END_NAMESPACE
static Value get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty);
static Value getIndexed(Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty);
static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value);
+ static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
static void destroy(Managed *that);
private:
0,
0,
isEqualTo,
+ 0,
"Managed",
};
return false;
}
-
Value Managed::get(ExecutionContext *ctx, String *name, bool *hasProperty)
{
return vtbl->get(this, ctx, name, hasProperty);
struct String;
struct Object;
struct ObjectPrototype;
+struct ObjectIterator;
struct ExecutionContext;
struct ScriptFunction;
struct InternalClass;
+struct Property;
struct BooleanObject;
struct NumberObject;
void (*getLookup)(Managed *m, ExecutionContext *ctx, Lookup *l, Value *result);
void (*setLookup)(Managed *m, ExecutionContext *ctx, Lookup *l, const Value &v);
bool (*isEqualTo)(Managed *m, Managed *other);
+ Property *(*advanceIterator)(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
const char *className;
};
getLookup, \
setLookup, \
isEqualTo, \
+ advanceIterator, \
#classname \
}
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); }
static void destroy(Managed *that) { that->_data = 0; }
static bool hasInstance(Managed *that, ExecutionContext *ctx, const Value &value);
private:
friend class MemoryManager;
friend struct Identifiers;
+ friend struct ObjectIterator;
};
}
o->put(ctx, l->name, value);
}
+Property *Object::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
+{
+ Object *o = static_cast<Object *>(m);
+ *name = 0;
+ *index = UINT_MAX;
+
+ if (!it->arrayIndex)
+ it->arrayNode = o->sparseArrayBegin();
+
+ // sparse arrays
+ if (it->arrayNode) {
+ while (it->arrayNode != o->sparseArrayEnd()) {
+ int k = it->arrayNode->key();
+ uint pidx = it->arrayNode->value;
+ Property *p = o->arrayData + pidx;
+ it->arrayNode = it->arrayNode->nextNode();
+ PropertyAttributes a = o->arrayAttributes ? o->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
+ if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
+ it->arrayIndex = k + 1;
+ *index = k;
+ if (attrs)
+ *attrs = a;
+ return p;
+ }
+ }
+ it->arrayNode = 0;
+ it->arrayIndex = UINT_MAX;
+ }
+ // dense arrays
+ while (it->arrayIndex < o->arrayDataLen) {
+ uint pidx = o->propertyIndexFromArrayIndex(it->arrayIndex);
+ Property *p = o->arrayData + pidx;
+ PropertyAttributes a = o->arrayAttributes ? o->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
+ ++it->arrayIndex;
+ if ((!o->arrayAttributes || !o->arrayAttributes[pidx].isGeneric())
+ && (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable())) {
+ *index = it->arrayIndex - 1;
+ if (attrs)
+ *attrs = a;
+ return p;
+ }
+ }
+
+ while (it->memberIndex < o->internalClass->size) {
+ String *n = o->internalClass->nameMap.at(it->memberIndex);
+ assert(n);
+ // ### check that it's not a repeated attribute
+
+ Property *p = o->memberData + it->memberIndex;
+ PropertyAttributes a = o->internalClass->propertyData[it->memberIndex];
+ ++it->memberIndex;
+ if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
+ *name = n;
+ if (attrs)
+ *attrs = a;
+ return p;
+ }
+ }
+
+ return 0;
+}
// Section 8.12.3
Value Object::internalGet(ExecutionContext *ctx, String *name, bool *hasProperty)
using Managed::deleteIndexedProperty;
using Managed::getLookup;
using Managed::setLookup;
+ using Managed::advanceIterator;
protected:
static const ManagedVTable static_vtbl;
static void destroy(Managed *that);
static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index);
static void getLookup(Managed *m, ExecutionContext *ctx, Lookup *l, Value *result);
static void setLookup(Managed *m, ExecutionContext *ctx, Lookup *l, const Value &v);
+ static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
private:
ObjectIterator::ObjectIterator(Object *o, uint flags)
: object(o)
- , internalClass(o ? o->internalClass : 0)
, current(o)
, arrayNode(0)
, arrayIndex(0)
, memberIndex(0)
, flags(flags)
- , wrappedListLength(0)
{
tmpDynamicProperty.value = Value::undefinedValue();
- if (current) {
- if (current->asStringObject())
- this->flags |= CurrentIsString;
-
- if (current->isListType()) {
- wrappedListLength = current->get(o->engine()->id_length).toUInt32();
- assert(current->arrayDataLen == 0);
- }
- }
}
Property *ObjectIterator::next(String **name, uint *index, PropertyAttributes *attrs)
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;
- if (attrs)
- *attrs = s->arrayAttributes ? s->arrayAttributes[arrayIndex] : PropertyAttributes(Attr_NotWritable|Attr_NotConfigurable);
- return s->__getOwnProperty__(*index);
- }
- flags &= ~CurrentIsString;
- arrayNode = current->sparseArrayBegin();
- // iterate until we're past the end of the string
- while (arrayNode && arrayNode->key() < slen)
- arrayNode = arrayNode->nextNode();
- }
-
- if (!arrayIndex)
- arrayNode = current->sparseArrayBegin();
-
- // sparse arrays
- if (arrayNode) {
- while (arrayNode != current->sparseArrayEnd()) {
- int k = arrayNode->key();
- uint pidx = arrayNode->value;
- p = current->arrayData + pidx;
- arrayNode = arrayNode->nextNode();
- PropertyAttributes a = current->arrayAttributes ? current->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- if (!(flags & EnumerableOnly) || a.isEnumerable()) {
- arrayIndex = k + 1;
- *index = k;
- if (attrs)
- *attrs = a;
- return p;
- }
- }
- arrayNode = 0;
- arrayIndex = UINT_MAX;
- }
- // dense arrays
- while (arrayIndex < current->arrayDataLen) {
- uint pidx = current->propertyIndexFromArrayIndex(arrayIndex);
- p = current->arrayData + pidx;
- PropertyAttributes a = current->arrayAttributes ? current->arrayAttributes[pidx] : PropertyAttributes(Attr_Data);
- ++arrayIndex;
- if ((!current->arrayAttributes || !current->arrayAttributes[pidx].isGeneric())
- && (!(flags & EnumerableOnly) || a.isEnumerable())) {
- *index = arrayIndex - 1;
- if (attrs)
- *attrs = a;
- return p;
- }
- }
-
- while (arrayIndex < wrappedListLength) {
- PropertyAttributes a = current->queryIndexed(arrayIndex);
- ++arrayIndex;
- if (!(flags & EnumerableOnly) || a.isEnumerable()) {
- *index = arrayIndex - 1;
- if (attrs)
- *attrs = a;
- tmpDynamicProperty.value = current->getIndexed(*index);
- return &tmpDynamicProperty;
- }
- }
-
- if (memberIndex == internalClass->size) {
- if (flags & WithProtoChain)
- current = current->prototype;
- else
- current = 0;
- if (current && current->asStringObject())
- flags |= CurrentIsString;
- else
- flags &= ~CurrentIsString;
-
- internalClass = current ? current->internalClass : 0;
-
- arrayIndex = 0;
- memberIndex = 0;
+ p = current->advanceIterator(this, name, index, attrs);
+ if (p)
+ return p;
- if (current && current->isListType()) {
- wrappedListLength = current->get(current->engine()->id_length).toUInt32();
- assert(current->arrayDataLen == 0);
- }
- continue;
- }
- String *n = internalClass->nameMap.at(memberIndex);
- assert(n);
- // ### check that it's not a repeated attribute
+ if (flags & WithProtoChain)
+ current = current->prototype;
+ else
+ current = 0;
- p = current->memberData + memberIndex;
- PropertyAttributes a = internalClass->propertyData[memberIndex];
- ++memberIndex;
- if (!(flags & EnumerableOnly) || a.isEnumerable()) {
- *name = n;
- if (attrs)
- *attrs = a;
- return p;
- }
+ arrayIndex = 0;
+ memberIndex = 0;
}
return 0;
}
NoFlags = 0,
EnumerableOnly = 0x1,
WithProtoChain = 0x2,
- CurrentIsString = 0x4
};
Object *object;
- InternalClass *internalClass;
Object *current;
SparseArrayNode *arrayNode;
uint arrayIndex;
uint flags;
Property tmpDynamicProperty;
- uint wrappedListLength;
ObjectIterator(Object *o, uint flags);
Property *next(String **name, uint *index, PropertyAttributes *attributes = 0);
{
return false;
}
+
+Property *RegExp::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes)
+{
+ return 0;
+}
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static bool deleteProperty(Managed *m, ExecutionContext *ctx, String *name);
static bool deleteIndexedProperty(Managed *m, ExecutionContext *ctx, uint index);
-
+ static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attributes);
private:
friend class RegExpCache;
F(QString, QString, QStringList, QString()) \
F(QUrl, Url, QList<QUrl>, QUrl())
-static QV4::Value convertElementToValue(QV4::ExecutionContext *ctx, const QString &element)
+static QV4::Value convertElementToValue(QV4::ExecutionEngine *engine, const QString &element)
{
- return QV4::Value::fromString(ctx, element);
+ return QV4::Value::fromString(engine, element);
}
-static QV4::Value convertElementToValue(QV4::ExecutionContext *ctx, int element)
+static QV4::Value convertElementToValue(QV4::ExecutionEngine *, int element)
{
return QV4::Value::fromInt32(element);
}
-static QV4::Value convertElementToValue(QV4::ExecutionContext *ctx, const QUrl &element)
+static QV4::Value convertElementToValue(QV4::ExecutionEngine *engine, const QUrl &element)
{
- return QV4::Value::fromString(ctx, element.toString());
+ return QV4::Value::fromString(engine, element.toString());
}
-static QV4::Value convertElementToValue(QV4::ExecutionContext *ctx, qreal element)
+static QV4::Value convertElementToValue(QV4::ExecutionEngine *, qreal element)
{
return QV4::Value::fromDouble(element);
}
-static QV4::Value convertElementToValue(QV4::ExecutionContext *ctx, bool element)
+static QV4::Value convertElementToValue(QV4::ExecutionEngine *, bool element)
{
return QV4::Value::fromBoolean(element);
}
if (signedIdx < m_container.count()) {
if (hasProperty)
*hasProperty = true;
- return convertElementToValue(ctx, m_container.at(signedIdx));
+ return convertElementToValue(ctx->engine, m_container.at(signedIdx));
}
if (hasProperty)
*hasProperty = false;
loadReference();
}
qint32 signedIdx = static_cast<qint32>(index);
- return (index < m_container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
+ return (signedIdx < m_container.count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
+ }
+
+ Property *containerAdvanceIterator(ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
+ {
+ *name = 0;
+ *index = UINT_MAX;
+
+ if (m_isReference) {
+ if (!m_object)
+ return QQmlSequenceBase::advanceIterator(this, it, name, index, attrs);
+ loadReference();
+ }
+
+ if (it->arrayIndex < m_container.count()) {
+ if (attrs)
+ *attrs = QV4::Attr_Data;
+ *index = it->arrayIndex;
+ ++it->arrayIndex;
+ it->tmpDynamicProperty.value = convertElementToValue(engine(), m_container.at(*index));
+ return &it->tmpDynamicProperty;
+ }
+ return QQmlSequenceBase::advanceIterator(this, it, name, index, attrs);
}
bool containerDeleteIndexedProperty(QV4::ExecutionContext *ctx, uint index)
{
QV4::Managed *fun = this->m_compareFn.asManaged();
QV4::Value argv[2] = {
- convertElementToValue(this->m_ctx, lhs),
- convertElementToValue(this->m_ctx, rhs)
+ convertElementToValue(this->m_ctx->engine, lhs),
+ convertElementToValue(this->m_ctx->engine, rhs)
};
QV4::Value result = fun->call(this->m_ctx, QV4::Value::fromObject(this->m_ctx->engine->globalObject), argv, 2);
return result.toNumber() < 0;
{ return static_cast<QQmlSequence<Container> *>(that)->containerDeleteIndexedProperty(ctx, 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)
+ { return static_cast<QQmlSequence<Container> *>(that)->containerAdvanceIterator(it, name, index, attrs); }
static void destroy(Managed *that)
{
0 /*getLookup*/,
0 /*setLookup*/,
Managed::isEqualTo,
+ 0 /*advanceIterator*/,
"String",
};
return &tmpProperty;
}
+Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs)
+{
+ StringObject *s = static_cast<StringObject *>(m);
+ uint slen = s->value.stringValue()->toQString().length();
+ if (it->arrayIndex < slen) {
+ while (it->arrayIndex < slen) {
+ *index = it->arrayIndex;
+ ++it->arrayIndex;
+ if (attrs)
+ *attrs = s->arrayAttributes ? s->arrayAttributes[it->arrayIndex] : PropertyAttributes(Attr_NotWritable|Attr_NotConfigurable);
+ return s->__getOwnProperty__(*index);
+ }
+ it->arrayNode = s->sparseArrayBegin();
+ // iterate until we're past the end of the string
+ while (it->arrayNode && it->arrayNode->key() < slen)
+ it->arrayNode = it->arrayNode->nextNode();
+ }
+
+ return Object::advanceIterator(m, it, name, index, attrs);
+}
+
void StringObject::markObjects(Managed *that)
{
StringObject *o = static_cast<StringObject *>(that);
Property *getIndex(uint index) const;
protected:
+ static Property *advanceIterator(Managed *m, ObjectIterator *it, String **name, uint *index, PropertyAttributes *attrs);
static const ManagedVTable static_vtbl;
static void markObjects(Managed *that);
};