Fixes to Array.prototype.indexOf
authorLars Knoll <lars.knoll@digia.com>
Thu, 17 Jan 2013 12:42:13 +0000 (13:42 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 17 Jan 2013 14:56:45 +0000 (15:56 +0100)
Change-Id: Ia9a2a8e25223c4b4d72a59c0c2ea449dc544f796
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4ecmaobjects.cpp

index b0e7bc3..602b64e 100644 (file)
@@ -1921,22 +1921,37 @@ Value ArrayPrototype::method_unshift(ExecutionContext *ctx)
 
 Value ArrayPrototype::method_indexOf(ExecutionContext *ctx)
 {
-    ArrayObject *instance = ctx->thisObject.asArrayObject();
-    if (!instance)
-        ctx->throwUnimplemented(QStringLiteral("Array.prototype.indexOf"));
+    Object *instance = __qmljs_to_object(ctx->thisObject, ctx).objectValue();
 
     Value searchValue;
     uint fromIndex = 0;
 
-    if (ctx->argumentCount == 1)
-        searchValue = ctx->argument(0);
-    else if (ctx->argumentCount == 2) {
+    if (ctx->argumentCount >= 1)
         searchValue = ctx->argument(0);
-        fromIndex = ctx->argument(1).toUInt32(ctx);
-    } else
-        __qmljs_throw_type_error(ctx);
+    else
+        return Value::fromInt32(-1);
 
     uint len = instance->isArray ? instance->array.length() : instance->__get__(ctx, ctx->engine->id_length).toUInt32(ctx);
+
+    if (ctx->argumentCount >= 2) {
+        double f = ctx->argument(1).toInteger(ctx);
+        if (f >= len)
+            return Value::fromInt32(-1);
+        if (f < 0)
+            f = qMax(len + f, 0.);
+        fromIndex = (uint) f;
+    }
+
+    if (instance->isString) {
+        for (uint k = fromIndex; k < len; ++k) {
+            bool exists;
+            Value v = instance->__get__(ctx, k, &exists);
+            if (exists && __qmljs_strict_equal(v, searchValue))
+                return Value::fromDouble(k);
+        }
+        return Value::fromInt32(-1);
+    }
+
     return instance->array.indexOf(searchValue, fromIndex, len, ctx, instance);
 }