aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-09-23 12:10:12 +0200
committerLars Knoll <lars.knoll@qt.io>2018-09-27 08:33:55 +0000
commitf63d48d474db7e9eff7583f1b8478228b13d3c82 (patch)
tree4bc1dd1f4f7b2f9a5df5b40247e1a8245169b903 /src
parent1804fea8893c355dbd585e373cb9644387410a92 (diff)
Differentiate between finding for get and set in InternalClass
This is required, so we can get rid of the requirement that getter and setter live next to each other in the member data. Change-Id: I2ed57a171628af4dfecd1836d00e958c6bed9d4f Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
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.