diff options
Diffstat (limited to 'src/qml/jsruntime/qv4object.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 02acc1a5e0..d1f71b18ae 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -93,19 +93,6 @@ void Heap::Object::setUsedAsProto() internalClass.set(internalClass->engine, internalClass->asProtoClass()); } -bool Object::setPrototype(Object *proto) -{ - Heap::Object *p = proto ? proto->d() : nullptr; - Heap::Object *pp = p; - while (pp) { - if (pp == d()) - return false; - pp = pp->prototype(); - } - setInternalClass(internalClass()->changePrototype(p)); - return true; -} - ReturnedValue Object::getValue(const Value &thisObject, const Value &v, PropertyAttributes attrs) { if (!attrs.isAccessor()) @@ -278,6 +265,11 @@ void Object::insertMember(StringOrSymbol *s, const Property *p, PropertyAttribut } } +void Object::setPrototypeUnchecked(const Object *p) +{ + setInternalClass(internalClass()->changePrototype(p ? p->d() : nullptr)); +} + // Section 8.12.2 PropertyIndex Object::getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs) { @@ -484,7 +476,7 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const return str.asReturnedValue(); } } - o = o->prototype(); + o = o->getPrototypeOf(); } if (exists) { @@ -543,13 +535,13 @@ bool Object::internalPut(StringOrSymbol *name, const Value &value) memberIndex.set(engine, value); } return true; - } else if (!prototype()) { + } else if (!getPrototypeOf()) { if (!isExtensible()) return false; } else { // clause 4 Scope scope(engine); - memberIndex = ScopedObject(scope, prototype())->getValueOrSetter(name, &attrs); + memberIndex = ScopedObject(scope, getPrototypeOf())->getValueOrSetter(name, &attrs); if (!memberIndex.isNull()) { if (attrs.isAccessor()) { if (!memberIndex->as<FunctionObject>()) @@ -608,13 +600,13 @@ bool Object::internalPutIndexed(uint index, const Value &value) arrayIndex.set(engine, value); return true; - } else if (!prototype()) { + } else if (!getPrototypeOf()) { if (!isExtensible()) return false; } else { // clause 4 Scope scope(engine); - arrayIndex = ScopedObject(scope, prototype())->getValueOrSetter(index, &attrs); + arrayIndex = ScopedObject(scope, getPrototypeOf())->getValueOrSetter(index, &attrs); if (!arrayIndex.isNull()) { if (attrs.isAccessor()) { if (!arrayIndex->as<FunctionObject>()) @@ -978,7 +970,7 @@ bool Object::hasProperty(const Managed *m, Identifier id) if (o->getOwnProperty(id, p) != Attr_Invalid) return true; - o = o->prototype(); + o = o->getPrototypeOf(); } return false; @@ -1033,6 +1025,34 @@ bool Object::preventExtensions(Managed *m) return true; } +Heap::Object *Object::getPrototypeOf(const Managed *m) +{ + return m->internalClass()->prototype; +} + +bool Object::setPrototypeOf(Managed *m, const Object *proto) +{ + Q_ASSERT(m->isObject()); + Object *o = static_cast<Object *>(m); + Heap::Object *current = o->internalClass()->prototype; + Heap::Object *protod = proto ? proto->d() : nullptr; + if (current == protod) + return true; + if (!o->internalClass()->extensible) + return false; + Heap::Object *p = protod; + while (p) { + if (p == o->d()) + return false; + if (reinterpret_cast<const ObjectVTable *>(p->vtable())->getPrototypeOf != + reinterpret_cast<const ObjectVTable *>(Object::staticVTable())->getPrototypeOf) + break; + p = p->prototype(); + } + o->setInternalClass(o->internalClass()->changePrototype(protod)); + return true; +} + bool Object::setArrayLength(uint newLen) { Q_ASSERT(isArrayObject()); |