Пример #1
0
ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, const Value &index)
{
    uint idx = index.asArrayIndex();
    if (idx == UINT_MAX || !object.isObject())
        return indexedGetterGeneric(l, object, index);

    Object *o = object.objectValue();
    if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
        Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
        if (idx < s->len)
            if (!s->data(idx).isEmpty())
                return s->data(idx).asReturnedValue();
    }

    return indexedGetterFallback(l, object, index);
}
Пример #2
0
void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value &index, const Value &v)
{
    uint idx = index.asArrayIndex();
    if (idx == UINT_MAX || !object.isObject()) {
        indexedSetterGeneric(l, object, index, v);
        return;
    }

    Object *o = object.objectValue();
    if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
        Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
        if (idx < s->len) {
            s->data(idx) = v;
            return;
        }
    }
    indexedSetterFallback(l, object, index, v);
}
Пример #3
0
void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &index, const Value &value)
{
    Scope scope(l->engine);
    ScopedObject o(scope, object.toObject(scope.engine));
    if (scope.engine->hasException)
        return;

    uint idx = index.asArrayIndex();
    if (idx < UINT_MAX) {
        if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
            Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->d()->arrayData);
            if (idx < s->len) {
                s->data(idx) = value;
                return;
            }
        }
        o->putIndexed(idx, value);
        return;
    }

    ScopedString name(scope, index.toString(scope.engine));
    o->put(name, value);
}
Пример #4
0
void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *pd, PropertyAttributes *attrs)
{
    Object *o = static_cast<Object *>(m);
    name->setM(0);
    *index = UINT_MAX;

    if (o->arrayData()) {
        if (!it->arrayIndex)
            it->arrayNode = o->sparseBegin();

        // sparse arrays
        if (it->arrayNode) {
            while (it->arrayNode != o->sparseEnd()) {
                int k = it->arrayNode->key();
                uint pidx = it->arrayNode->value;
                Heap::SparseArrayData *sa = o->d()->arrayData.cast<Heap::SparseArrayData>();
                const Property *p = reinterpret_cast<const Property *>(sa->values.data() + pidx);
                it->arrayNode = it->arrayNode->nextNode();
                PropertyAttributes a = sa->attrs ? sa->attrs[pidx] : Attr_Data;
                if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
                    it->arrayIndex = k + 1;
                    *index = k;
                    *attrs = a;
                    pd->copy(p, a);
                    return;
                }
            }
            it->arrayNode = 0;
            it->arrayIndex = UINT_MAX;
        }
        // dense arrays
        while (it->arrayIndex < o->d()->arrayData->values.size) {
            Heap::SimpleArrayData *sa = o->d()->arrayData.cast<Heap::SimpleArrayData>();
            const Value &val = sa->data(it->arrayIndex);
            PropertyAttributes a = o->arrayData()->attributes(it->arrayIndex);
            ++it->arrayIndex;
            if (!val.isEmpty()
                && (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable())) {
                *index = it->arrayIndex - 1;
                *attrs = a;
                pd->value = val;
                return;
            }
        }
    }

    while (it->memberIndex < o->internalClass()->size) {
        Identifier *n = o->internalClass()->nameMap.at(it->memberIndex);
        if (!n) {
            // accessor properties have a dummy entry with n == 0
            ++it->memberIndex;
            continue;
        }

        int idx = it->memberIndex;
        PropertyAttributes a = o->internalClass()->propertyData[it->memberIndex];
        ++it->memberIndex;
        if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
            name->setM(o->engine()->identifierTable->stringFromIdentifier(n));
            *attrs = a;
            pd->value = *o->propertyData(idx);
            if (a.isAccessor())
                pd->set = *o->propertyData(idx + SetterOffset);
            return;
        }
    }

    *attrs = PropertyAttributes();
}