aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4context.cpp6
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h15
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp11
-rw-r--r--src/qml/jsruntime/qv4object.cpp24
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp4
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.