diff options
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 15 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 24 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext.cpp | 4 |
7 files changed, 38 insertions, 26 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 9cebe6f043..43aa2e931e 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -61,7 +61,7 @@ void Heap::StrictArgumentsObject::init(QV4::CppStackFrame *frame) Q_ASSERT(internalClass->verifyIndex(v4->id_callee()->propertyKey(), CalleePropertyIndex)); Q_ASSERT(internalClass->verifyIndex(v4->symbol_iterator()->propertyKey(), SymbolIteratorPropertyIndex)); setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues()); - setProperty(v4, CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower()); + setProperty(v4, CalleePropertyIndex, *v4->thrower()); setProperty(v4, CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower()); Scope scope(v4); diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 38e233965f..94b1a9fb73 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -295,11 +295,11 @@ ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value Q_FALLTHROUGH(); case Heap::ExecutionContext::Type_GlobalContext: if (ctx->activation) { - uint member = ctx->activation->internalClass->indexOfValueOrGetter(id); - if (member < UINT_MAX) { + auto member = ctx->activation->internalClass->findValueOrSetter(id); + if (member.index < UINT_MAX) { Scope scope(engine); ScopedObject a(scope, ctx->activation); - if (!a->putValue(member, value)) + if (!a->putValue(member.index, member.attrs, value)) return TypeError; return NoError; } diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index 82ace19d30..cced746568 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -369,7 +369,7 @@ struct InternalClass : Base { bool isValid() const { return index != UINT_MAX; } }; - IndexAndAttribute find(const PropertyKey id) + IndexAndAttribute findValueOrGetter(const PropertyKey id) { Q_ASSERT(id.isStringOrSymbol()); @@ -380,6 +380,19 @@ struct InternalClass : Base { return { UINT_MAX, Attr_Invalid }; } + IndexAndAttribute findValueOrSetter(const PropertyKey id) + { + Q_ASSERT(id.isStringOrSymbol()); + + PropertyHash::Entry *e = propertyTable.lookup(id); + if (e && e->index < size) { + PropertyAttributes a = propertyData.at(e->index); + return { a.isAccessor() ? e->index + 1 : e->index, a }; + } + + return { UINT_MAX, Attr_Invalid }; + } + uint indexOfValueOrGetter(const PropertyKey id) { Q_ASSERT(id.isStringOrSymbol()); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 141d9b5afb..994daa864b 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -50,7 +50,7 @@ using namespace QV4; void Lookup::resolveProtoGetter(PropertyKey name, const Heap::Object *proto) { while (proto) { - auto index = proto->internalClass->find(name); + auto index = proto->internalClass->findValueOrGetter(name); if (index.isValid()) { PropertyAttributes attrs = index.attrs; protoLookup.data = proto->propertyData(index.index); @@ -77,7 +77,7 @@ ReturnedValue Lookup::resolveGetter(ExecutionEngine *engine, const Object *objec return getter(this, engine, *object); } - auto index = obj->internalClass->find(name); + auto index = obj->internalClass->findValueOrGetter(name); if (index.isValid()) { PropertyAttributes attrs = index.attrs; uint nInline = obj->vtable()->nInlineProperties; @@ -478,9 +478,10 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value Heap::InternalClass *c = object->internalClass(); PropertyKey key = name->toPropertyKey(); - auto idx = c->find(key); + auto idx = c->findValueOrSetter(key); if (idx.isValid()) { if (object->isArrayObject() && idx.index == Heap::ArrayObject::LengthPropertyIndex) { + Q_ASSERT(!idx.attrs.isAccessor()); setter = arrayLengthSetter; return setter(this, engine, *object, value); } else if (idx.attrs.isData() && idx.attrs.isWritable()) { @@ -506,8 +507,8 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value setter = setterFallback; return true; } - idx = object->internalClass()->find(key); - if (!idx.isValid()) { // ### can this even happen? + idx = object->internalClass()->findValueOrSetter(key); + if (!idx.isValid() || idx.attrs.isAccessor()) { // ### can this even happen? setter = setterFallback; return false; } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 476ecf7f2a..855bebff88 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -108,16 +108,14 @@ ReturnedValue Object::getValueAccessor(const Value &thisObject, const Value &v, return f->call(jsCallData); } -bool Object::putValue(uint memberIndex, const Value &value) +bool Object::putValue(uint memberIndex, PropertyAttributes attrs, const Value &value) { Heap::InternalClass *ic = internalClass(); if (ic->engine->hasException) return false; - PropertyAttributes attrs = ic->propertyData[memberIndex]; - if (attrs.isAccessor()) { - const FunctionObject *set = propertyData(memberIndex + SetterOffset)->as<FunctionObject>(); + const FunctionObject *set = propertyData(memberIndex)->as<FunctionObject>(); if (set) { Scope scope(ic->engine); ScopedFunctionObject setter(scope, set); @@ -256,7 +254,7 @@ void Object::insertMember(StringOrSymbol *s, const Property *p, PropertyAttribut Heap::InternalClass::addMember(this, key, attributes, &idx); if (attributes.isAccessor()) { - setProperty(idx + GetterOffset, p->value); + setProperty(idx, p->value); setProperty(idx + SetterOffset, p->set); } else { setProperty(idx, p->value); @@ -295,10 +293,10 @@ PropertyIndex Object::getValueOrSetter(PropertyKey id, PropertyAttributes *attrs } else { Heap::Object *o = d(); while (o) { - auto idx = o->internalClass->find(id); + auto idx = o->internalClass->findValueOrSetter(id); if (idx.isValid()) { *attrs = idx.attrs; - return o->writablePropertyData(attrs->isAccessor() ? idx.index + SetterOffset : idx.index ); + return o->writablePropertyData(idx.index); } o = o->prototype(); @@ -443,7 +441,7 @@ ReturnedValue Object::internalGet(PropertyKey id, const Value *receiver, bool *h Q_ASSERT(!id.isArrayIndex()); while (1) { - auto idx = o->internalClass->find(id); + auto idx = o->internalClass->findValueOrGetter(id); if (idx.isValid()) { if (hasProperty) *hasProperty = true; @@ -488,10 +486,10 @@ bool Object::internalPut(PropertyKey id, const Value &value, Value *receiver) if (arrayData()) propertyIndex = arrayData()->getValueOrSetter(index, &attrs); } else { - auto member = internalClass()->find(id); + auto member = internalClass()->findValueOrSetter(id); if (member.isValid()) { attrs = member.attrs; - propertyIndex = d()->writablePropertyData(member.attrs.isAccessor() ? member.index + SetterOffset : member.index); + propertyIndex = d()->writablePropertyData(member.index); } } @@ -588,7 +586,7 @@ bool Object::internalDeleteProperty(PropertyKey id) return false; } - auto memberIdx = internalClass()->find(id); + auto memberIdx = internalClass()->findValueOrGetter(id); if (memberIdx.isValid()) { if (memberIdx.attrs.isConfigurable()) { Heap::InternalClass::removeMember(this, id); @@ -804,7 +802,7 @@ PropertyAttributes Object::virtualGetOwnProperty(const Managed *m, PropertyKey i } else { Q_ASSERT(id.asStringOrSymbol()); - auto member = o->internalClass()->find(id); + auto member = o->internalClass()->findValueOrGetter(id); if (member.isValid()) { attrs = member.attrs; if (p) { @@ -854,7 +852,7 @@ bool Object::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property return o->internalDefineOwnProperty(scope.engine, index, nullptr, p, attrs); } - auto memberIndex = o->internalClass()->find(id); + auto memberIndex = o->internalClass()->findValueOrGetter(id); Scoped<StringOrSymbol> name(scope, id.asStringOrSymbol()); if (!memberIndex.isValid()) { diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index c9b0ff7e1f..a32f8a4dac 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -197,7 +197,7 @@ struct Q_QML_EXPORT Object: Managed { } static ReturnedValue getValueAccessor(const Value &thisObject, const Value &v, PropertyAttributes attrs); - bool putValue(uint memberIndex, const Value &value); + bool putValue(uint memberIndex, PropertyAttributes attrs, const Value &value); /* The spec default: Writable: true, Enumerable: false, Configurable: true */ void defineDefaultProperty(StringOrSymbol *name, const Value &value, PropertyAttributes attributes = Attr_Data|Attr_NotEnumerable) { diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index b10065d308..cc0b0feeee 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -265,9 +265,9 @@ bool QQmlContextWrapper::virtualPut(Managed *m, PropertyKey id, const Value &val return false; QV4::Scoped<QQmlContextWrapper> wrapper(scope, resource); - auto member = wrapper->internalClass()->find(id); + auto member = wrapper->internalClass()->findValueOrSetter(id); if (member.index < UINT_MAX) - return wrapper->putValue(member.index, value); + return wrapper->putValue(member.index, member.attrs, value); // It's possible we could delay the calculation of the "actual" context (in the case // of sub contexts) until it is definitely needed. |