Implement Array.prototype.map
authorRoberto Raggi <roberto.raggi@nokia.com>
Mon, 21 May 2012 15:59:54 +0000 (17:59 +0200)
committerRoberto Raggi <roberto.raggi@nokia.com>
Mon, 21 May 2012 15:59:54 +0000 (17:59 +0200)
qv4ecmaobjects.cpp
tests/fun.4.js

index cebf999..82d59a2 100644 (file)
@@ -1410,8 +1410,12 @@ void ArrayPrototype::method_every(Context *ctx)
             Value thisArg = ctx->argument(1);
             bool ok = true;
             for (uint k = 0; ok && k < instance->value.size(); ++k) {
+                Value v = instance->value.at(k);
+                if (v.isUndefined())
+                    continue;
+
                 Value args[3];
-                args[0] = instance->value.at(k);
+                args[0] = v;
                 args[1] = Value::fromNumber(k);
                 args[2] = ctx->thisObject;
                 Value r;
@@ -1436,8 +1440,12 @@ void ArrayPrototype::method_some(Context *ctx)
             Value thisArg = ctx->argument(1);
             bool ok = false;
             for (uint k = 0; !ok && k < instance->value.size(); ++k) {
+                Value v = instance->value.at(k);
+                if (v.isUndefined())
+                    continue;
+
                 Value args[3];
-                args[0] = instance->value.at(k);
+                args[0] = v;
                 args[1] = Value::fromNumber(k);
                 args[2] = ctx->thisObject;
                 Value r;
@@ -1483,7 +1491,27 @@ void ArrayPrototype::method_map(Context *ctx)
 {
     Value self = ctx->thisObject;
     if (ArrayObject *instance = self.asArrayObject()) {
-        Q_UNIMPLEMENTED();
+        Value callback = ctx->argument(0);
+        if (! callback.isFunctionObject())
+            assert(!"type error");
+        else {
+            Value thisArg = ctx->argument(1);
+            ArrayObject *a = ctx->engine->newArrayObject()->asArrayObject();
+            a->value.resize(instance->value.size());
+            for (quint32 k = 0; k < instance->value.size(); ++k) {
+                Value v = instance->value.at(k);
+                if (v.isUndefined())
+                    continue;
+                Value r;
+                Value args[3];
+                args[0] = v;
+                args[1] = Value::fromNumber(k);
+                args[2] = ctx->thisObject;
+                __qmljs_call_value(ctx, &r, &thisArg, &callback, args, 3);
+                a->value.assign(k, r);
+            }
+            ctx->result = Value::fromObject(a);
+        }
     } else {
         assert(!"generic implementation");
     }
index 7741b26..e35c8ac 100644 (file)
@@ -9,5 +9,6 @@ foo.call(null, 1,2,3);
 
 print([10, 20, 30].every(function (v,k,o) { return v > 9 }));
 print([10, 20, 30].some(function (v,k,o) { return v == 20 }));
+print([10, 20, 30].map(function (v,k,o) { return v * v }));