Fix Array.prototype.sort for non sparse arrays
authorLars Knoll <lars.knoll@digia.com>
Wed, 16 Jan 2013 14:41:02 +0000 (15:41 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 16 Jan 2013 17:21:57 +0000 (18:21 +0100)
Change-Id: Ibb055358dc953881842d43ebff4d361c949796a9
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4array.cpp
qv4array.h
qv4ecmaobjects.cpp
qv4ecmaobjects_p.h
tests/TestExpectations

index 42c7ed9..c9942b0 100644 (file)
@@ -569,14 +569,19 @@ void Array::concat(const Array &other)
     setLengthUnchecked(newLen);
 }
 
-void Array::sort(ExecutionContext *context, Object *thisObject, const Value &comparefn)
+void Array::sort(ExecutionContext *context, Object *thisObject, const Value &comparefn, uint len)
 {
-    if (!sparse)
+    if (sparse) {
+        context->throwUnimplemented("Array::sort unimplemented for sparse arrays");
         return;
+        delete sparse;
+    }
 
     ArrayElementLessThan lessThan(context, thisObject, comparefn);
-    std::sort(values.begin(), values.end(), lessThan);
-    delete sparse;
+    if (len > values.size() - offset)
+        len = values.size() - offset;
+    PropertyDescriptor *begin = values.begin() + offset;
+    std::sort(begin, begin + len, lessThan);
 }
 
 
index bdd3744..28601ba 100644 (file)
@@ -608,7 +608,7 @@ public:
     SparseArrayNode *sparseEnd() { return sparse ? sparse->end() : 0; }
 
     void concat(const Array &other);
-    void sort(ExecutionContext *context, Object *thisObject, const Value &comparefn);
+    void sort(ExecutionContext *context, Object *thisObject, const Value &comparefn, uint len);
     void splice(double start, double deleteCount, const QVector<Value> &, Array &);
     Value indexOf(Value v, uint fromIndex, uint len, ExecutionContext *ctx, Object *o);
 };
index f3fd4ac..9310676 100644 (file)
@@ -1613,6 +1613,13 @@ void ArrayPrototype::init(ExecutionContext *ctx, const Value &ctor)
     defineDefaultProperty(ctx, QStringLiteral("reduceRight"), method_reduceRight, 1);
 }
 
+uint ArrayPrototype::getLength(ExecutionContext *ctx, Object *o)
+{
+    if (o->isArray)
+        return o->array.length();
+    return o->__get__(ctx, ctx->engine->id_length).toUInt32(ctx);
+}
+
 Value ArrayPrototype::method_isArray(ExecutionContext *ctx)
 {
     Value arg = ctx->argument(0);
@@ -1824,12 +1831,12 @@ Value ArrayPrototype::method_slice(ExecutionContext *ctx)
 
 Value ArrayPrototype::method_sort(ExecutionContext *ctx)
 {
-    ArrayObject *instance = ctx->thisObject.asArrayObject();
-    if (!instance)
-        ctx->throwUnimplemented(QStringLiteral("Array.prototype.sort"));
+    Object *instance = __qmljs_to_object(ctx->thisObject, ctx).objectValue();
+
+    uint len = getLength(ctx, instance);
 
     Value comparefn = ctx->argument(0);
-    instance->array.sort(ctx, instance, comparefn);
+    instance->array.sort(ctx, instance, comparefn, len);
     return ctx->thisObject;
 }
 
index 53936be..35a3f65 100644 (file)
@@ -175,6 +175,8 @@ struct ArrayPrototype: ArrayObject
 
     void init(ExecutionContext *ctx, const Value &ctor);
 
+    static uint getLength(ExecutionContext *ctx, Object *o);
+
     static Value method_isArray(ExecutionContext *ctx);
     static Value method_toString(ExecutionContext *ctx);
     static Value method_toLocaleString(ExecutionContext *ctx);
index d9f6088..839ba7c 100644 (file)
@@ -793,7 +793,6 @@ S15.1.3.2_A5.3 failing
 15.2.3.3-4-82 failing
 15.2.3.3-4-9 failing
 15.2.3.3-4-90 failing
-15.2.3.4-4-44 failing
 15.2.3.5-4-120 failing
 15.2.3.5-4-13 failing
 15.2.3.5-4-145 failing
@@ -860,12 +859,6 @@ S15.1.3.2_A5.3 failing
 15.2.3.7-6-a-289 failing
 15.3.4.5-2-7 failing
 15.4.3.2-1-11 failing
-S15.4.4.11_A3_T1 failing
-S15.4.4.11_A3_T2 failing
-S15.4.4.11_A4_T1 failing
-S15.4.4.11_A4_T2 failing
-S15.4.4.11_A4_T3 failing
-S15.4.4.11_A6_T2 failing
 15.4.4.12-9-c-ii-1 failing
 S15.4.4.12_A1.1_T4 failing
 S15.4.4.12_A1.1_T6 failing
@@ -2759,15 +2752,6 @@ S15.2.4.4_A14 failing
 S15.2.4.4_A15 failing
 
 # Array regressions
-S13.2.1_A5_T1 failing
-S15.4.4.11_A1.5_T1 failing
-S15.4.4.11_A2.1_T1 failing
-S15.4.4.11_A2.1_T2 failing
-S15.4.4.11_A2.1_T3 failing
-S15.4.4.11_A2.2_T1 failing
-S15.4.4.11_A2.2_T2 failing
-S15.4.4.11_A2.2_T3 failing
-S15.4.4.11_A5_T1 failing
 15.4.4.12-9-a-1 failing
 S15.4.4.12_A1.1_T1 failing
 S15.4.4.12_A1.1_T2 failing
@@ -2788,10 +2772,6 @@ S15.4.4.12_A2.1_T4 failing
 S15.4.4.12_A2.1_T5 failing
 S15.4.4.12_A2.2_T3 failing
 S15.4.4.12_A2.2_T5 failing
-S15.4.4.11_A1.2_T1 failing
-S15.4.4.11_A1.2_T2 failing
-S15.4.4.11_A1.4_T1 failing
-S15.4.4.11_A1.4_T2 failing
 S15.4.4.4_A1_T2 failing
 
 # Regressions due to Object/property refactoring