From 50d6e51c73a37858699b90d64657cec5e0b53610 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 8 Jan 2014 12:46:53 +0100 Subject: clean up Object::has(Own)Property hasProperty is now implemented by calling hasOwnProperty on the proto chain. In addition, it should be slightly faster and doesn't use API that returns a Property pointer anymore. Change-Id: I6312d83ccfed3f0a1a8ec4c72c436a426d6eab44 Reviewed-by: Simon Hausmann --- src/qml/jsapi/qjsvalue.cpp | 2 +- src/qml/jsruntime/qv4context.cpp | 10 ++++----- src/qml/jsruntime/qv4object.cpp | 41 +++++++++++++++++++++++++----------- src/qml/jsruntime/qv4object_p.h | 4 ++-- src/qml/jsruntime/qv4objectproto.cpp | 12 +++++------ src/qml/jsruntime/qv4runtime.cpp | 2 +- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 8e1ac38f4f..0734e92b19 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -1028,7 +1028,7 @@ bool QJSValue::hasProperty(const QString &name) const return false; ScopedString s(scope, engine->newIdentifier(name)); - return o->__hasProperty__(s); + return o->hasProperty(s); } /*! diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 36b1512b63..f808a5791f 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -152,7 +152,7 @@ void ExecutionContext::createMutableBinding(const StringRef name, bool deletable ctx = ctx->outer; } - if (activation->__hasProperty__(name)) + if (activation->hasProperty(name)) return; Property desc = Property::fromValue(Primitive::undefinedValue()); PropertyAttributes attrs(Attr_Data); @@ -256,7 +256,7 @@ bool ExecutionContext::deleteProperty(const StringRef name) if (ctx->type == Type_WithContext) { hasWith = true; WithContext *w = static_cast(ctx); - if (w->withObject->__hasProperty__(name)) + if (w->withObject->hasProperty(name)) return w->withObject->deleteProperty(name); } else if (ctx->type == Type_CatchContext) { CatchContext *c = static_cast(ctx); @@ -271,11 +271,11 @@ bool ExecutionContext::deleteProperty(const StringRef name) // ### throw in strict mode? return false; } - if (c->activation && c->activation->__hasProperty__(name)) + if (c->activation && c->activation->hasProperty(name)) return c->activation->deleteProperty(name); } else if (ctx->type == Type_GlobalContext) { GlobalContext *g = static_cast(ctx); - if (g->global->__hasProperty__(name)) + if (g->global->hasProperty(name)) return g->global->deleteProperty(name); } } @@ -328,7 +328,7 @@ void ExecutionContext::setProperty(const StringRef name, const ValueRef value) for (ExecutionContext *ctx = this; ctx; ctx = ctx->outer) { if (ctx->type == Type_WithContext) { ScopedObject w(scope, static_cast(ctx)->withObject); - if (w->__hasProperty__(name)) { + if (w->hasProperty(name)) { w->put(name, value); return; } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 819a2f6f0b..0814613ebf 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -356,30 +356,30 @@ Property *Object::__getPropertyDescriptor__(uint index, PropertyAttributes *attr return 0; } -bool Object::__hasProperty__(const StringRef name) const +bool Object::hasProperty(const StringRef name) const { - if (__getPropertyDescriptor__(name)) - return true; + uint idx = name->asArrayIndex(); + if (idx != UINT_MAX) + return hasProperty(idx); const Object *o = this; while (o) { - if (!o->query(name).isEmpty()) + if (o->hasOwnProperty(name)) return true; + o = o->prototype(); } return false; } -bool Object::__hasProperty__(uint index) const +bool Object::hasProperty(uint index) const { - if (__getPropertyDescriptor__(index)) - return true; - const Object *o = this; while (o) { - if (!o->queryIndexed(index).isEmpty()) - return true; + if (o->hasOwnProperty(index)) + return true; + o = o->prototype(); } @@ -388,12 +388,29 @@ bool Object::__hasProperty__(uint index) const bool Object::hasOwnProperty(const StringRef name) const { - return const_cast(this)->__getOwnProperty__(name) != 0; + uint idx = name->asArrayIndex(); + if (idx != UINT_MAX) + return hasOwnProperty(idx); + + if (internalClass->find(name) < UINT_MAX) + return true; + if (!query(name).isEmpty()) + return true; + return false; } bool Object::hasOwnProperty(uint index) const { - return const_cast(this)->__getOwnProperty__(index) != 0; + if (!arrayData->isEmpty(index)) + return true; + if (isStringObject()) { + String *s = static_cast(this)->value.asString(); + if (index < (uint)s->length()) + return true; + } + if (!queryIndexed(index).isEmpty()) + return true; + return false; } ReturnedValue Object::get(Managed *m, const StringRef name, bool *hasProperty) diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 9500c2a4d0..d84b553b66 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -130,8 +130,8 @@ struct Q_QML_EXPORT Object: Managed { Property *__getPropertyDescriptor__(const StringRef name, PropertyAttributes *attrs = 0) const; Property *__getPropertyDescriptor__(uint index, PropertyAttributes *attrs = 0) const; - bool __hasProperty__(const StringRef name) const; - bool __hasProperty__(uint index) const; + bool hasProperty(const StringRef name) const; + bool hasProperty(uint index) const; bool hasOwnProperty(const StringRef name) const; bool hasOwnProperty(uint index) const; diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index ac19101a29..9474442a70 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -596,13 +596,13 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef desc->setSetter(0); ScopedValue tmp(scope); - if (o->__hasProperty__(ctx->engine->id_enumerable)) + if (o->hasProperty(ctx->engine->id_enumerable)) attrs->setEnumerable((tmp = o->get(ctx->engine->id_enumerable))->toBoolean()); - if (o->__hasProperty__(ctx->engine->id_configurable)) + if (o->hasProperty(ctx->engine->id_configurable)) attrs->setConfigurable((tmp = o->get(ctx->engine->id_configurable))->toBoolean()); - if (o->__hasProperty__(ctx->engine->id_get)) { + if (o->hasProperty(ctx->engine->id_get)) { ScopedValue get(scope, o->get(ctx->engine->id_get)); FunctionObject *f = get->asFunctionObject(); if (f) { @@ -616,7 +616,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef attrs->setType(PropertyAttributes::Accessor); } - if (o->__hasProperty__(ctx->engine->id_set)) { + if (o->hasProperty(ctx->engine->id_set)) { ScopedValue set(scope, o->get(ctx->engine->id_set)); FunctionObject *f = set->asFunctionObject(); if (f) { @@ -630,7 +630,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef attrs->setType(PropertyAttributes::Accessor); } - if (o->__hasProperty__(ctx->engine->id_writable)) { + if (o->hasProperty(ctx->engine->id_writable)) { if (attrs->isAccessor()) { ctx->throwTypeError(); return; @@ -640,7 +640,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef desc->value = Primitive::undefinedValue(); } - if (o->__hasProperty__(ctx->engine->id_value)) { + if (o->hasProperty(ctx->engine->id_value)) { if (attrs->isAccessor()) { ctx->throwTypeError(); return; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 9275704984..4c7ec6602d 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -338,7 +338,7 @@ QV4::ReturnedValue __qmljs_in(ExecutionContext *ctx, const ValueRef left, const ScopedString s(scope, left->toString(ctx)); if (scope.hasException()) return Encode::undefined(); - bool r = right->objectValue()->__hasProperty__(s); + bool r = right->objectValue()->hasProperty(s); return Encode(r); } -- cgit v1.2.3