aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4lookup.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-11-14 09:54:00 +0100
committerLars Knoll <lars.knoll@qt.io>2017-11-27 11:10:04 +0000
commite6d17c8691bfafa033b82a4d81a9caf4a2fd1b85 (patch)
tree68a8774562cf291eb4350facfd7feece4dd77443 /src/qml/jsruntime/qv4lookup.cpp
parentfca89004d75412dd378cc44ad79ed3c1e05c765b (diff)
Convert setters to use the id in InternalClass
Change-Id: I7f3acf96e998a41d60d33f98b243089b9ee40ff0 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4lookup.cpp')
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp165
1 files changed, 94 insertions, 71 deletions
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index c690c59270..73ae4bf410 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -508,32 +508,81 @@ ReturnedValue Lookup::globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engi
return globalGetterGeneric(l, engine);
}
-bool Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value &value)
{
Scope scope(engine);
- ScopedObject o(scope, object);
- if (!o) {
- o = RuntimeHelpers::convertToObject(scope.engine, object);
- if (!o) // type error
- return false;
- ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
- return o->put(name, value);
+ ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+
+ InternalClass *c = object->internalClass();
+ uint idx = c->find(name);
+ if (idx != UINT_MAX) {
+ if (object->isArrayObject() && idx == Heap::ArrayObject::LengthPropertyIndex) {
+ setter = arrayLengthSetter;
+ return setter(this, engine, *object, value);
+ } else if (object->internalClass()->propertyData[idx].isData() && object->internalClass()->propertyData[idx].isWritable()) {
+ objectLookup.ic = object->internalClass();
+ objectLookup.offset = idx;
+ setter = idx < object->d()->vtable()->nInlineProperties ? Lookup::setter0Inline : Lookup::setter0;
+ return setter(this, engine, *object, value);
+ } else {
+ // ### handle setter
+ setter = setterFallback;
+ }
+ return setter(this, engine, *object, value);
}
- return o->setLookup(l, value);
+
+ insertionLookup.icIdentifier = c->id;
+ if (!object->put(name, value)) {
+ setter = Lookup::setterFallback;
+ return false;
+ }
+
+ if (object->internalClass() == c) {
+ // ### setter in the prototype, should handle this
+ setter = setterFallback;
+ return true;
+ }
+ idx = object->internalClass()->find(name);
+ if (idx == UINT_MAX) { // ### can this even happen?
+ setter = setterFallback;
+ return false;
+ }
+ insertionLookup.newClass = object->internalClass();
+ insertionLookup.offset = idx;
+ setter = setterInsert;
+ return true;
+}
+
+bool Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+{
+ if (object.isObject())
+ return l->resolveSetter(engine, static_cast<Object *>(&object), value);
+
+ Scope scope(engine);
+ ScopedObject o(scope, RuntimeHelpers::convertToObject(scope.engine, object));
+ if (!o) // type error
+ return false;
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ return o->put(name, value);
}
bool Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Lookup l1 = *l;
+ Lookup first = *l;
+ Lookup second = *l;
- if (Object *o = object.as<Object>()) {
- if (!o->setLookup(l, value))
+ if (object.isObject()) {
+ if (!l->resolveSetter(engine, static_cast<Object *>(&object), value)) {
+ l->setter = setterFallback;
return false;
+ }
if (l->setter == Lookup::setter0 || l->setter == Lookup::setter0Inline) {
+ l->objectLookupTwoClasses.ic = first.objectLookup.ic;
+ l->objectLookupTwoClasses.ic2 = second.objectLookup.ic;
+ l->objectLookupTwoClasses.offset = first.objectLookup.offset;
+ l->objectLookupTwoClasses.offset2 = second.objectLookup.offset;
l->setter = setter0setter0;
- l->classList[1] = l1.classList[0];
- l->index2 = l1.index;
return true;
}
}
@@ -555,9 +604,9 @@ bool Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, c
bool Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- o->setProperty(engine, l->index, value);
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (o && o->internalClass == l->objectLookup.ic) {
+ o->setProperty(engine, l->objectLookup.offset, value);
return true;
}
@@ -566,39 +615,25 @@ bool Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Va
bool Lookup::setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- o->d()->setInlineProperty(engine, l->index, value);
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (o && o->internalClass == l->objectLookup.ic) {
+ o->setInlineProperty(engine, l->objectLookup.offset, value);
return true;
}
return setterTwoClasses(l, engine, object, value);
}
-bool Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
-{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- Q_ASSERT(!o->prototype());
- o->setInternalClass(l->classList[3]);
- o->setProperty(l->index, value);
- return true;
- }
-
- l->setter = setterFallback;
- return setterFallback(l, engine, object, value);
-}
-
-bool Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- Heap::Object *p = o->prototype();
- Q_ASSERT(p);
- if (p->internalClass == l->classList[1]) {
- Q_ASSERT(!p->prototype());
- o->setInternalClass(l->classList[3]);
- o->setProperty(l->index, value);
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (o) {
+ if (o->internalClass == l->objectLookupTwoClasses.ic) {
+ o->setProperty(engine, l->objectLookupTwoClasses.offset, value);
+ return true;
+ }
+ if (o->internalClass == l->objectLookupTwoClasses.ic2) {
+ o->setProperty(engine, l->objectLookupTwoClasses.offset2, value);
return true;
}
}
@@ -607,44 +642,32 @@ bool Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, co
return setterFallback(l, engine, object, value);
}
-bool Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- Heap::Object *p = o->prototype();
- Q_ASSERT(p);
- if (p->internalClass == l->classList[1]) {
- p = p->prototype();
- Q_ASSERT(p);
- if (p->internalClass == l->classList[2]) {
- Q_ASSERT(!p->prototype());
- o->setInternalClass(l->classList[3]);
- o->setProperty(l->index, value);
- return true;
- }
- }
+ if (o && o->internalClass()->id == l->insertionLookup.icIdentifier) {
+ o->setInternalClass(l->insertionLookup.newClass);
+ o->d()->setProperty(engine, l->insertionLookup.offset, value);
+ return true;
}
l->setter = setterFallback;
return setterFallback(l, engine, object, value);
}
-bool Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::arrayLengthSetter(Lookup *, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o) {
- if (o->internalClass() == l->classList[0]) {
- o->setProperty(l->index, value);
- return true;
- }
- if (o->internalClass() == l->classList[1]) {
- o->setProperty(l->index2, value);
- return true;
- }
+ Q_ASSERT(object.isObject() && static_cast<Object &>(object).isArrayObject());
+ bool ok;
+ uint len = value.asArrayLength(&ok);
+ if (!ok) {
+ engine->throwRangeError(value);
+ return false;
}
-
- l->setter = setterFallback;
- return setterFallback(l, engine, object, value);
+ ok = static_cast<Object &>(object).setArrayLength(len);
+ if (!ok)
+ return false;
+ return true;
}
QT_END_NAMESPACE