diff options
author | Lars Knoll <[email protected]> | 2013-12-16 09:16:57 +0100 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-01-09 07:47:06 +0100 |
commit | 459c9a2a8840995436e610459216957bc7ebd914 (patch) | |
tree | ef28df2fdbc62bf551088d13850492d2c6a771b1 /src/qml/jsruntime/qv4runtime.cpp | |
parent | 5cf95512af83fc6a0f70d3493be571accaf50d84 (diff) |
Rework array handling for JS objects
Split up ArrayData into two classes, one for regular
arrays, one for sparse arrays and cleanly separate
the two cases. Only create array data on demand.
Change-Id: I9ca8d0b53592174f213ba0f20caf93e77dba690a
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src/qml/jsruntime/qv4runtime.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 79 |
1 files changed, 28 insertions, 51 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 23549fe7ef..91ddfd01de 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -589,12 +589,10 @@ ReturnedValue __qmljs_get_element(ExecutionContext *ctx, const ValueRef object, } if (idx < UINT_MAX) { - uint pidx = o->propertyIndexFromArrayIndex(idx); - if (pidx < UINT_MAX) { - if (!o->arrayData.attributes || o->arrayData.attributes[pidx].isData()) { - if (!o->arrayData.data[pidx].value.isEmpty()) - return o->arrayData.data[pidx].value.asReturnedValue(); - } + if (!o->arrayData->hasAttributes()) { + ScopedValue v(scope, o->arrayData->get(idx)); + if (!v->isEmpty()) + return v->asReturnedValue(); } return o->getIndexed(idx); @@ -615,36 +613,10 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val uint idx = index->asArrayIndex(); if (idx < UINT_MAX) { - uint pidx = o->propertyIndexFromArrayIndex(idx); - if (pidx < UINT_MAX && !o->asArgumentsObject()) { - if (o->arrayData.attributes && !o->arrayData.attributes[pidx].isEmpty() && !o->arrayData.attributes[pidx].isWritable()) { - if (ctx->strictMode) - ctx->throwTypeError(); - return; - } - - Property *p = o->arrayData.data + pidx; - if (!o->arrayData.attributes || o->arrayData.attributes[pidx].isData()) { - p->value = *value; - return; - } - - if (o->arrayData.attributes[pidx].isAccessor()) { - FunctionObject *setter = p->setter(); - if (!setter) { - if (ctx->strictMode) - ctx->throwTypeError(); - return; - } - - ScopedCallData callData(scope, 1); - callData->thisObject = o; - callData->args[0] = *value; - setter->call(callData); - return; - } - } - o->putIndexed(idx, value); + if (idx < o->arrayData->length() && o->arrayType() == ArrayData::Simple) + o->arrayData->put(idx, value); + else + o->putIndexed(idx, value); return; } @@ -1118,25 +1090,23 @@ void __qmljs_builtin_define_property(ExecutionContext *ctx, const ValueRef objec assert(o); uint idx = name->asArrayIndex(); - Property *pd = (idx != UINT_MAX) ? o->arrayInsert(idx) : o->insertMember(name, Attr_Data); - pd->value = val ? *val : Primitive::undefinedValue(); + if (idx != UINT_MAX) { + o->arraySet(idx, val); + } else { + Property *pd = o->insertMember(name, Attr_Data); + pd->value = val ? *val : Primitive::undefinedValue(); + } } -ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, Value *values, uint length) +ReturnedValue __qmljs_builtin_define_array(ExecutionContext *ctx, SafeValue *values, uint length) { Scope scope(ctx); Scoped<ArrayObject> a(scope, ctx->engine->newArrayObject()); - // ### FIXME: We need to allocate the array data to avoid crashes other places - // This should rather be done when required - a->arrayReserve(length); if (length) { - a->arrayData.length = length; - Property *pd = a->arrayData.data; - for (uint i = 0; i < length; ++i) { - pd->value = values[i]; - ++pd; - } + a->arrayReserve(length); + a->arrayData->setLength(length); + a->arrayData->put(0, values, length); a->setArrayLengthUnchecked(length); } return a.asReturnedValue(); @@ -1149,9 +1119,16 @@ void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef Q_ASSERT(!!o); uint idx = name->asArrayIndex(); - Property *pd = (idx != UINT_MAX) ? o->arrayInsert(idx, Attr_Accessor) : o->insertMember(name, Attr_Accessor); - pd->setGetter(getter ? getter->asFunctionObject() : 0); - pd->setSetter(setter ? setter->asFunctionObject() : 0); + if (idx != UINT_MAX) { + Property pd; + pd.setGetter(getter ? getter->asFunctionObject() : 0); + pd.setSetter(setter ? setter->asFunctionObject() : 0); + o->arraySet(idx, pd, Attr_Accessor); + } else { + Property *pd = o->insertMember(name, Attr_Accessor); + pd->setGetter(getter ? getter->asFunctionObject() : 0); + pd->setSetter(setter ? setter->asFunctionObject() : 0); + } } ReturnedValue __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId) |