diff options
Diffstat (limited to 'src/qml/jsruntime/qv4lookup.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index 4ee24d29eb..f67b24c040 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -49,16 +49,6 @@ using namespace QV4; Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs) { int i = 0; - while (i < level && obj && obj->internalClass == classList[i]) { - obj = obj->prototype(); - ++i; - } - - if (index != UINT_MAX && obj->internalClass == classList[i]) { - *attrs = obj->internalClass->propertyData.at(index); - return obj->memberData + index; - } - while (i < Size && obj) { classList[i] = obj->internalClass; @@ -72,7 +62,7 @@ Property *Lookup::lookup(Object *obj, PropertyAttributes *attrs) obj = obj->prototype(); ++i; } - level = i; + level = Size; while (obj) { index = obj->internalClass->find(name); @@ -97,7 +87,7 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object) switch (object->type()) { case Value::Undefined_Type: case Value::Null_Type: - engine->current->throwTypeError(); + return engine->current->throwTypeError(); case Value::Boolean_Type: proto = engine->booleanClass->prototype; break; @@ -140,9 +130,12 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object) ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object) { - if (Object *o = object->asObject()) { + if (object->isManaged()) { + // we can safely cast to a QV4::Object here. If object is actually a string, + // the internal class won't match + Object *o = object->objectValue(); if (l->classList[0] == o->internalClass) - return o->memberData[l->index].value.asReturnedValue(); + return static_cast<Object *>(o)->memberData[l->index].value.asReturnedValue(); } l->getter = getterGeneric; return getterGeneric(l, object); @@ -150,7 +143,10 @@ ReturnedValue Lookup::getter0(Lookup *l, const ValueRef object) ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object) { - if (Object *o = object->asObject()) { + if (object->isManaged()) { + // we can safely cast to a QV4::Object here. If object is actually a string, + // the internal class won't match + Object *o = object->objectValue(); if (l->classList[0] == o->internalClass && l->classList[1] == o->prototype()->internalClass) return o->prototype()->memberData[l->index].value.asReturnedValue(); @@ -161,7 +157,10 @@ ReturnedValue Lookup::getter1(Lookup *l, const ValueRef object) ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object) { - if (Object *o = object->asObject()) { + if (object->isManaged()) { + // we can safely cast to a QV4::Object here. If object is actually a string, + // the internal class won't match + Object *o = object->objectValue(); if (l->classList[0] == o->internalClass) { o = o->prototype(); if (l->classList[1] == o->internalClass) { @@ -177,7 +176,10 @@ ReturnedValue Lookup::getter2(Lookup *l, const ValueRef object) ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object) { - if (Object *o = object->asObject()) { + if (object->isManaged()) { + // we can safely cast to a QV4::Object here. If object is actually a string, + // the internal class won't match + Object *o = object->objectValue(); if (l->classList[0] == o->internalClass) { Scope scope(o->engine()); FunctionObject *getter = o->memberData[l->index].getter(); @@ -195,7 +197,10 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, const ValueRef object) ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object) { - if (Object *o = object->asObject()) { + if (object->isManaged()) { + // we can safely cast to a QV4::Object here. If object is actually a string, + // the internal class won't match + Object *o = object->objectValue(); if (l->classList[0] == o->internalClass && l->classList[1] == o->prototype()->internalClass) { Scope scope(o->engine()); @@ -214,7 +219,10 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, const ValueRef object) ReturnedValue Lookup::getterAccessor2(Lookup *l, const ValueRef object) { - if (Object *o = object->asObject()) { + if (object->isManaged()) { + // we can safely cast to a QV4::Object here. If object is actually a string, + // the internal class won't match + Object *o = object->objectValue(); if (l->classList[0] == o->internalClass) { o = o->prototype(); if (l->classList[1] == o->internalClass) { @@ -335,7 +343,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx) } Scope scope(ctx); Scoped<String> n(scope, l->name); - ctx->throwReferenceError(n); + return ctx->throwReferenceError(n); } ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx) @@ -439,6 +447,8 @@ void Lookup::setterGeneric(Lookup *l, const ValueRef object, const ValueRef valu ScopedObject o(scope, object); if (!o) { o = __qmljs_convert_to_object(scope.engine->current, object); + if (!o) // type error + return; ScopedString s(scope, l->name); o->put(s, value); return; @@ -463,6 +473,8 @@ void Lookup::setterInsert0(Lookup *l, const ValueRef object, const ValueRef valu Object *o = object->asObject(); if (o && o->internalClass == l->classList[0]) { if (!o->prototype()) { + if (l->index >= o->memberDataAlloc) + o->ensureMemberIndex(l->index); o->memberData[l->index].value = *value; o->internalClass = l->classList[3]; return; @@ -479,6 +491,8 @@ void Lookup::setterInsert1(Lookup *l, const ValueRef object, const ValueRef valu if (o && o->internalClass == l->classList[0]) { Object *p = o->prototype(); if (p && p->internalClass == l->classList[1]) { + if (l->index >= o->memberDataAlloc) + o->ensureMemberIndex(l->index); o->memberData[l->index].value = *value; o->internalClass = l->classList[3]; return; @@ -497,7 +511,8 @@ void Lookup::setterInsert2(Lookup *l, const ValueRef object, const ValueRef valu if (p && p->internalClass == l->classList[1]) { p = p->prototype(); if (p && p->internalClass == l->classList[2]) { - o->ensureMemberIndex(l->index); + if (l->index >= o->memberDataAlloc) + o->ensureMemberIndex(l->index); o->memberData[l->index].value = *value; o->internalClass = l->classList[3]; return; |