Fix ownKey iteration over Proxy objects

Change-Id: I045a4844c06df9232cc8b04485ab0a39bb990e3f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2018-09-08 22:29:47 +02:00
parent 5d470f5121
commit 009a125d07
26 changed files with 51 additions and 40 deletions

View File

@ -64,7 +64,7 @@ void QJSValueIteratorPrivate::init(const QJSValue &v)
engine = e;
object = o;
iterator.reset(o->ownPropertyKeys());
iterator.reset(o->ownPropertyKeys(object.valueRef()));
next();
}

View File

@ -213,8 +213,8 @@ qint64 ArgumentsObject::virtualGetLength(const Managed *m)
return a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->toLength();
}
OwnPropertyKeyIterator *ArgumentsObject::virtualOwnPropertyKeys(const Object *m)
OwnPropertyKeyIterator *ArgumentsObject::virtualOwnPropertyKeys(const Object *m, Value *target)
{
static_cast<ArgumentsObject *>(const_cast<Object *>(m))->fullyCreate();
return Object::virtualOwnPropertyKeys(m);
return Object::virtualOwnPropertyKeys(m, target);
}

View File

@ -106,7 +106,7 @@ struct ArgumentsObject: Object {
static bool virtualDeleteProperty(Managed *m, PropertyKey id);
static PropertyAttributes virtualGetOwnProperty(Managed *m, PropertyKey id, Property *p);
static qint64 virtualGetLength(const Managed *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
void fullyCreate();

View File

@ -214,9 +214,10 @@ PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, Propert
return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
}
OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o)
OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o, Value *target)
{
const Module *module = static_cast<const Module *>(o);
*target = *o;
return new ModuleNamespaceIterator(module->d()->unit->exportedNames());
}

View File

@ -82,7 +82,7 @@ struct Q_QML_EXPORT Module : public Object {
static bool virtualDefineOwnProperty(Managed *, PropertyKey, const Property *, PropertyAttributes);
static bool virtualPut(Managed *, PropertyKey, const Value &, Value *);
static bool virtualDeleteProperty(Managed *m, PropertyKey id);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static Heap::Object *virtualGetPrototypeOf(const Managed *);
static bool virtualSetPrototypeOf(Managed *, const Object *proto);
static bool virtualIsExtensible(const Managed *);

View File

@ -390,8 +390,9 @@ PropertyKey ObjectOwnPropertyKeyIterator::next(const Object *o, Property *pd, Pr
return PropertyKey::invalid();
}
OwnPropertyKeyIterator *Object::virtualOwnPropertyKeys(const Object *)
OwnPropertyKeyIterator *Object::virtualOwnPropertyKeys(const Object *o, Value *target)
{
*target = *o;
return new ObjectOwnPropertyKeyIterator;
}

View File

@ -353,8 +353,8 @@ public:
bool deleteProperty(PropertyKey id)
{ return vtable()->deleteProperty(this, id); }
OwnPropertyKeyIterator *ownPropertyKeys() const
{ return vtable()->ownPropertyKeys(this); }
OwnPropertyKeyIterator *ownPropertyKeys(Value *target) const
{ return vtable()->ownPropertyKeys(this, target); }
qint64 getLength() const { return vtable()->getLength(this); }
ReturnedValue instanceOf(const Value &var) const
{ return vtable()->instanceOf(this, var); }
@ -374,7 +374,7 @@ protected:
static bool virtualPreventExtensions(Managed *);
static Heap::Object *virtualGetPrototypeOf(const Managed *);
static bool virtualSetPrototypeOf(Managed *, const Object *);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static qint64 virtualGetLength(const Managed *m);
static ReturnedValue virtualInstanceOf(const Object *typeObject, const Value &var);

View File

@ -164,6 +164,7 @@ PropertyKey ForInIteratorObject::nextProperty() const
Scope scope(this);
ScopedObject c(scope, d()->current);
ScopedObject t(scope, d()->target);
ScopedObject o(scope);
ScopedProperty p(scope);
ScopedPropertyKey key(scope);
@ -171,7 +172,7 @@ PropertyKey ForInIteratorObject::nextProperty() const
while (1) {
while (1) {
key = d()->iterator->next(c, p, &attrs);
key = d()->iterator->next(t, p, &attrs);
if (!key->isValid())
break;
if (!attrs.isEnumerable() || key->isSymbol())
@ -198,7 +199,8 @@ PropertyKey ForInIteratorObject::nextProperty() const
if (!c)
break;
delete d()->iterator;
d()->iterator = c->ownPropertyKeys();
d()->iterator = c->ownPropertyKeys(t.getRef());
d()->target.set(scope.engine, t->d());
if (!d()->iterator) {
scope.engine->throwTypeError();
return PropertyKey::invalid();

View File

@ -75,7 +75,8 @@ struct Q_QML_EXPORT ObjectIterator
object = static_cast<Object *>(scope.alloc());
this->flags = flags;
object->setM(o ? o->m() : nullptr);
iterator = object->ownPropertyKeys();
if (o)
iterator = object->ownPropertyKeys(object);
}
~ObjectIterator()
{
@ -93,6 +94,7 @@ namespace Heap {
#define ForInIteratorObjectMembers(class, Member) \
Member(class, Pointer, Object *, object) \
Member(class, Pointer, Object *, current) \
Member(class, Pointer, Object *, target) \
Member(class, NoMark, OwnPropertyKeyIterator *, iterator)
DECLARE_HEAP_OBJECT(ForInIteratorObject, Object) {
@ -130,7 +132,10 @@ void Heap::ForInIteratorObject::init(QV4::Object *o)
return;
object.set(o->engine(), o->d());
current.set(o->engine(), o->d());
iterator = o->ownPropertyKeys();
Scope scope(o);
ScopedObject obj(scope);
iterator = o->ownPropertyKeys(obj.getRef());
target.set(o->engine(), obj->d());
}

View File

@ -546,7 +546,7 @@ static bool removeAllOccurrences(ArrayObject *target, ReturnedValue val) {
return found;
}
OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m)
OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Value *iteratorTarget)
{
Scope scope(m);
const ProxyObject *o = static_cast<const ProxyObject *>(m);
@ -564,7 +564,7 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m)
if (scope.hasException())
return nullptr;
if (trap->isUndefined())
return target->ownPropertyKeys();
return target->ownPropertyKeys(iteratorTarget);
if (!trap->isFunctionObject()) {
scope.engine->throwTypeError();
return nullptr;
@ -637,12 +637,13 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m)
len = uncheckedResultKeys->getLength();
for (uint i = 0; i < len; ++i) {
if (targetConfigurableKeys->get(i) != Encode::undefined()) {
if (uncheckedResultKeys->get(i) != Encode::undefined()) {
scope.engine->throwTypeError();
return nullptr;
}
}
*iteratorTarget = *m;
return new ProxyObjectOwnPropertyKeyIterator(trapKeys);
}

View File

@ -110,7 +110,7 @@ struct ProxyObject : FunctionObject {
static bool virtualPreventExtensions(Managed *);
static Heap::Object *virtualGetPrototypeOf(const Managed *);
static bool virtualSetPrototypeOf(Managed *, const Object *);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *iteratorTarget);
};
struct ProxyFunctionObject : ProxyObject {

View File

@ -823,8 +823,9 @@ PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const Object *o, Property
return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
}
OwnPropertyKeyIterator *QObjectWrapper::virtualOwnPropertyKeys(const Object *)
OwnPropertyKeyIterator *QObjectWrapper::virtualOwnPropertyKeys(const Object *m, Value *target)
{
*target = *m;
return new QObjectWrapperOwnPropertyKeyIterator;
}

View File

@ -195,7 +195,7 @@ protected:
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
static PropertyAttributes virtualGetOwnProperty(Managed *m, PropertyKey id, Property *p);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static ReturnedValue method_connect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_disconnect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);

View File

@ -369,8 +369,9 @@ public:
}
};
static OwnPropertyKeyIterator *containerOwnPropertyKeys(const Object *)
static OwnPropertyKeyIterator *containerOwnPropertyKeys(const Object *m, Value *target)
{
*target = *m;
return new OwnPropertyKeyIterator;
}
@ -596,8 +597,8 @@ public:
}
static bool virtualIsEqualTo(Managed *that, Managed *other)
{ return static_cast<QQmlSequence<Container> *>(that)->containerIsEqualTo(other); }
static QV4::OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m)
{ return static_cast<const QQmlSequence<Container> *>(m)->containerOwnPropertyKeys(m);}
static QV4::OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target)
{ return static_cast<const QQmlSequence<Container> *>(m)->containerOwnPropertyKeys(m, target);}
};

View File

@ -140,8 +140,9 @@ PropertyKey StringObjectOwnPropertyKeyIterator::next(const Object *o, Property *
return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
}
OwnPropertyKeyIterator *StringObject::virtualOwnPropertyKeys(const Object *)
OwnPropertyKeyIterator *StringObject::virtualOwnPropertyKeys(const Object *m, Value *target)
{
*target = *m;
return new StringObjectOwnPropertyKeyIterator;
}

View File

@ -101,7 +101,7 @@ struct StringObject: Object {
using Object::getOwnProperty;
protected:
static bool virtualDeleteProperty(Managed *m, PropertyKey id);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static PropertyAttributes virtualGetOwnProperty(Managed *m, PropertyKey id, Property *p);
};

View File

@ -78,7 +78,7 @@ struct VTable
typedef Heap::Object *(*GetPrototypeOf)(const Managed *);
typedef bool (*SetPrototypeOf)(Managed *, const Object *);
typedef qint64 (*GetLength)(const Managed *m);
typedef OwnPropertyKeyIterator *(*OwnPropertyKeys)(const Object *m);
typedef OwnPropertyKeyIterator *(*OwnPropertyKeys)(const Object *m, Value *target);
typedef ReturnedValue (*InstanceOf)(const Object *typeObject, const Value &var);
typedef ReturnedValue (*Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);

View File

@ -165,8 +165,9 @@ PropertyKey QmlListWrapperOwnPropertyKeyIterator::next(const Object *o, Property
return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
}
OwnPropertyKeyIterator *QmlListWrapper::virtualOwnPropertyKeys(const Object *)
OwnPropertyKeyIterator *QmlListWrapper::virtualOwnPropertyKeys(const Object *m, Value *target)
{
*target = *m;
return new QmlListWrapperOwnPropertyKeyIterator;
}

View File

@ -95,7 +95,7 @@ struct Q_QML_EXPORT QmlListWrapper : Object
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
};
struct PropertyListPrototype : Object

View File

@ -289,8 +289,9 @@ PropertyKey QQmlValueTypeWrapperOwnPropertyKeyIterator::next(const Object *o, Pr
}
OwnPropertyKeyIterator *QQmlValueTypeWrapper::virtualOwnPropertyKeys(const Object *)
OwnPropertyKeyIterator *QQmlValueTypeWrapper::virtualOwnPropertyKeys(const Object *m, Value *target)
{
*target = *m;
return new QQmlValueTypeWrapperOwnPropertyKeyIterator;
}

View File

@ -110,8 +110,7 @@ public:
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
static bool virtualIsEqualTo(Managed *m, Managed *other);
static PropertyAttributes virtualGetOwnProperty(Managed *m, PropertyKey id, Property *p);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static ReturnedValue method_toString(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static void initProto(ExecutionEngine *v4);

View File

@ -219,13 +219,13 @@ ReturnedValue QtObject::virtualGet(const Managed *m, PropertyKey id, const Value
return ret;
}
OwnPropertyKeyIterator *QtObject::virtualOwnPropertyKeys(const Object *m)
OwnPropertyKeyIterator *QtObject::virtualOwnPropertyKeys(const Object *m, Value *target)
{
auto that = static_cast<const QtObject*>(m);
if (!that->d()->isComplete())
const_cast<QtObject *>(that)->addAll();
return Object::virtualOwnPropertyKeys(m);
return Object::virtualOwnPropertyKeys(m, target);
}
/*!

View File

@ -94,7 +94,7 @@ struct QtObject : Object
V4_OBJECT2(QtObject, Object)
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
static ReturnedValue method_isQtObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_rgba(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);

View File

@ -1646,8 +1646,9 @@ PropertyKey ModelObjectOwnPropertyKeyIterator::next(const Object *o, Property *p
return ObjectOwnPropertyKeyIterator::next(o, pd, attrs);
}
OwnPropertyKeyIterator *ModelObject::virtualOwnPropertyKeys(const Object *)
OwnPropertyKeyIterator *ModelObject::virtualOwnPropertyKeys(const Object *m, Value *target)
{
*target = *m;
return new ModelObjectOwnPropertyKeyIterator;
}

View File

@ -181,7 +181,7 @@ struct ModelObject : public QObjectWrapper
protected:
static bool virtualPut(Managed *m, PropertyKey id, const Value& value, Value *receiver);
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m);
static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m, Value *target);
};
} // namespace QV4

View File

@ -329,14 +329,10 @@ built-ins/Promise/resolve/name.js fails
built-ins/Promise/resolve/prop-desc.js fails
built-ins/Promise/resolve/resolve-from-promise-capability.js fails
built-ins/Promise/resolve/resolve-prms-cstm-then.js fails
built-ins/Proxy/enumerate/removed-does-not-trigger.js fails
built-ins/Proxy/getOwnPropertyDescriptor/trap-is-undefined.js fails
built-ins/Proxy/has/call-object-create.js fails
built-ins/Proxy/ownKeys/call-parameters-object-getownpropertysymbols.js fails
built-ins/Proxy/ownKeys/not-extensible-return-keys.js fails
built-ins/Proxy/ownKeys/return-duplicate-entries-throws.js fails
built-ins/Proxy/ownKeys/return-duplicate-symbol-entries-throws.js fails
built-ins/Proxy/ownKeys/trap-is-undefined.js fails
built-ins/Proxy/revocable/revocation-function-name.js fails
built-ins/RegExp/S15.10.2.12_A2_T1.js fails
built-ins/RegExp/prototype/Symbol.match/builtin-success-u-return-val-groups.js fails