Optimise array access
Optimise accessing indexed properties in Objects and Arrays Change-Id: I3330a4151a13e8f34fee1c4641e64d00a52625e2 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
parent
5ed9321942
commit
403ddb70fb
|
@ -280,7 +280,8 @@ Value Object::__get__(ExecutionContext *ctx, String *name, bool *hasProperty)
|
|||
|
||||
Value Object::__get__(ExecutionContext *ctx, uint index, bool *hasProperty)
|
||||
{
|
||||
if (const PropertyDescriptor *p = __getPropertyDescriptor__(ctx, index)) {
|
||||
const PropertyDescriptor *p = __getPropertyDescriptor__(ctx, index);
|
||||
if (p && p->type != PropertyDescriptor::Generic) {
|
||||
if (hasProperty)
|
||||
*hasProperty = true;
|
||||
return getValue(ctx, p);
|
||||
|
|
|
@ -575,23 +575,30 @@ void __qmljs_set_property(ExecutionContext *ctx, Value object, String *name, Val
|
|||
|
||||
Value __qmljs_get_element(ExecutionContext *ctx, Value object, Value index)
|
||||
{
|
||||
uint type = object.type();
|
||||
uint idx = index.asArrayIndex();
|
||||
|
||||
if (object.isString() && idx < UINT_MAX) {
|
||||
String *str = object.stringValue();
|
||||
if (idx >= (uint)str->toQString().length())
|
||||
return Value::undefinedValue();
|
||||
const QString s = str->toQString().mid(idx, 1);
|
||||
return Value::fromString(ctx, s);
|
||||
}
|
||||
if (type != Value::Object_Type) {
|
||||
if (type == Value::String_Type) {
|
||||
String *str = object.stringValue();
|
||||
if (idx >= (uint)str->toQString().length())
|
||||
return Value::undefinedValue();
|
||||
const QString s = str->toQString().mid(idx, 1);
|
||||
return Value::fromString(ctx, s);
|
||||
}
|
||||
|
||||
if (!object.isObject())
|
||||
object = __qmljs_to_object(object, ctx);
|
||||
}
|
||||
|
||||
Object *o = object.objectValue();
|
||||
|
||||
if (idx < UINT_MAX)
|
||||
if (idx < UINT_MAX) {
|
||||
const PropertyDescriptor *p = o->array.nonSparseAt(idx);
|
||||
if (p && p->type == PropertyDescriptor::Data)
|
||||
return p->value;
|
||||
|
||||
return o->__get__(ctx, idx);
|
||||
}
|
||||
|
||||
String *name = index.toString(ctx);
|
||||
return o->__get__(ctx, name);
|
||||
|
@ -606,6 +613,11 @@ void __qmljs_set_element(ExecutionContext *ctx, Value object, Value index, Value
|
|||
|
||||
uint idx = index.asArrayIndex();
|
||||
if (idx < UINT_MAX) {
|
||||
PropertyDescriptor *p = o->array.nonSparseAtRef(idx);
|
||||
if (p && p->type == PropertyDescriptor::Data && p->isWritable()) {
|
||||
p->value = value;
|
||||
return;
|
||||
}
|
||||
o->__put__(ctx, idx, value);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -521,6 +521,15 @@ public:
|
|||
return values.constData() + index;
|
||||
}
|
||||
|
||||
PropertyDescriptor *nonSparseAtRef(uint index) {
|
||||
if (sparse)
|
||||
return 0;
|
||||
index += offset;
|
||||
if (index >= (uint)values.size())
|
||||
return 0;
|
||||
return values.data() + index;
|
||||
}
|
||||
|
||||
const PropertyDescriptor *at(uint index) const {
|
||||
if (!sparse) {
|
||||
if (index >= values.size() - offset)
|
||||
|
|
Loading…
Reference in New Issue