aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4object.cpp')
-rw-r--r--src/qml/jsruntime/qv4object.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 9d6cb730a9..7dd0a247d6 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -736,6 +736,88 @@ ReturnedValue Object::virtualInstanceOf(const Object *typeObject, const Value &v
return checkedInstanceOf(engine, function, var);
}
+ReturnedValue Object::virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup)
+{
+ Heap::Object *obj = object->d();
+ PropertyKey name = engine->identifierTable->asPropertyKey(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[lookup->nameIndex]);
+ if (name.isArrayIndex()) {
+ lookup->indexedLookup.index = name.asArrayIndex();
+ lookup->getter = Lookup::getterIndexed;
+ return lookup->getter(lookup, engine, *object);
+ }
+
+ auto index = obj->internalClass->findValueOrGetter(name);
+ if (index.isValid()) {
+ PropertyAttributes attrs = index.attrs;
+ uint nInline = obj->vtable()->nInlineProperties;
+ if (attrs.isData()) {
+ if (index.index < obj->vtable()->nInlineProperties) {
+ index.index += obj->vtable()->inlinePropertyOffset;
+ lookup->getter = Lookup::getter0Inline;
+ } else {
+ index.index -= nInline;
+ lookup->getter = Lookup::getter0MemberData;
+ }
+ } else {
+ lookup->getter = Lookup::getterAccessor;
+ }
+ lookup->objectLookup.ic = obj->internalClass;
+ lookup->objectLookup.offset = index.index;
+ return lookup->getter(lookup, engine, *object);
+ }
+
+ lookup->protoLookup.protoId = obj->internalClass->protoId;
+ lookup->resolveProtoGetter(name, obj->prototype());
+ return lookup->getter(lookup, engine, *object);
+}
+
+bool Object::virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value)
+{
+ Scope scope(engine);
+ ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[lookup->nameIndex]);
+
+ Heap::InternalClass *c = object->internalClass();
+ PropertyKey key = name->toPropertyKey();
+ auto idx = c->findValueOrSetter(key);
+ if (idx.isValid()) {
+ if (object->isArrayObject() && idx.index == Heap::ArrayObject::LengthPropertyIndex) {
+ Q_ASSERT(!idx.attrs.isAccessor());
+ lookup->setter = Lookup::arrayLengthSetter;
+ return lookup->setter(lookup, engine, *object, value);
+ } else if (idx.attrs.isData() && idx.attrs.isWritable()) {
+ lookup->objectLookup.ic = object->internalClass();
+ lookup->objectLookup.offset = idx.index;
+ lookup->setter = idx.index < object->d()->vtable()->nInlineProperties ? Lookup::setter0Inline : Lookup::setter0;
+ return lookup->setter(lookup, engine, *object, value);
+ } else {
+ // ### handle setter
+ lookup->setter = Lookup::setterFallback;
+ }
+ return lookup->setter(lookup, engine, *object, value);
+ }
+
+ lookup->insertionLookup.protoId = c->protoId;
+ if (!object->put(key, value)) {
+ lookup->setter = Lookup::setterFallback;
+ return false;
+ }
+
+ if (object->internalClass() == c) {
+ // ### setter in the prototype, should handle this
+ lookup->setter = Lookup::setterFallback;
+ return true;
+ }
+ idx = object->internalClass()->findValueOrSetter(key);
+ if (!idx.isValid() || idx.attrs.isAccessor()) { // ### can this even happen?
+ lookup->setter = Lookup::setterFallback;
+ return false;
+ }
+ lookup->insertionLookup.newClass = object->internalClass();
+ lookup->insertionLookup.offset = idx.index;
+ lookup->setter = Lookup::setterInsert;
+ return true;
+}
+
ReturnedValue Object::checkedInstanceOf(ExecutionEngine *engine, const FunctionObject *f, const Value &var)
{
Scope scope(engine);