Jacek Caban : jscript: Add Array.prototype.forEach implementation.

Alexandre Julliard julliard at winehq.org
Wed Dec 5 15:49:01 CST 2018


Module: wine
Branch: master
Commit: cda846b8cbc39c07ce360a6660a1c8b2e2aca24b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cda846b8cbc39c07ce360a6660a1c8b2e2aca24b

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Dec  5 20:42:27 2018 +0100

jscript: Add Array.prototype.forEach implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/jscript/array.c              | 45 ++++++++++++++++++++++++++++++++++++++-
 dlls/mshtml/tests/documentmode.js |  1 +
 dlls/mshtml/tests/es5.js          | 24 ++++++++++++++++++++-
 3 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index e74ca7f..28289cb 100644
--- a/dlls/jscript/array.c
+++ b/dlls/jscript/array.c
@@ -36,6 +36,7 @@ typedef struct {
 
 static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
 static const WCHAR concatW[] = {'c','o','n','c','a','t',0};
+static const WCHAR forEachW[] = {'f','o','r','E','a','c','h',0};
 static const WCHAR joinW[] = {'j','o','i','n',0};
 static const WCHAR popW[] = {'p','o','p',0};
 static const WCHAR pushW[] = {'p','u','s','h',0};
@@ -947,6 +948,47 @@ static HRESULT Array_toLocaleString(script_ctx_t *ctx, vdisp_t *vthis, WORD flag
     return E_NOTIMPL;
 }
 
+static HRESULT Array_forEach(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
+        jsval_t *r)
+{
+    jsval_t value, args[3], res;
+    jsdisp_t *jsthis;
+    unsigned length, i;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    /* FIXME: Check IsCallable */
+    if(argc != 1 || !is_object_instance(argv[0])) {
+        FIXME("Unsupported arguments\n");
+        return E_NOTIMPL;
+    }
+
+    hres = get_length(ctx, vthis, &jsthis, &length);
+    if(FAILED(hres))
+        return hres;
+
+    for(i = 0; i < length; i++) {
+        hres = jsdisp_get_idx(jsthis, i, &value);
+        if(hres == DISP_E_UNKNOWNNAME)
+            continue;
+        if(FAILED(hres))
+            return hres;
+
+        args[0] = value;
+        args[1] = jsval_number(i);
+        args[2] = jsval_obj(jsthis);
+        hres = disp_call_value(ctx, get_object(argv[0]), NULL, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res);
+        jsval_release(value);
+        if(FAILED(hres))
+            return hres;
+        jsval_release(res);
+    }
+
+    if(r) *r = jsval_undefined();
+    return S_OK;
+}
+
 static HRESULT Array_indexOf(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
 {
@@ -1100,7 +1142,8 @@ static void Array_on_put(jsdisp_t *dispex, const WCHAR *name)
 
 static const builtin_prop_t Array_props[] = {
     {concatW,                Array_concat,               PROPF_METHOD|1},
-    {indexOfW,               Array_indexOf,              PROPF_ES5|PROPF_METHOD|1},
+    {forEachW,               Array_forEach,              PROPF_METHOD|PROPF_ES5|1},
+    {indexOfW,               Array_indexOf,              PROPF_METHOD|PROPF_ES5|1},
     {joinW,                  Array_join,                 PROPF_METHOD|1},
     {lengthW,                NULL,0,                     Array_get_length, Array_set_length},
     {popW,                   Array_pop,                  PROPF_METHOD},
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 9884def..58c7a4c 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -187,6 +187,7 @@ function test_javascript() {
     test_exposed("now", Date, true);
     test_exposed("toISOString", Date.prototype, v >= 9);
     test_exposed("isArray", Array, v >= 9);
+    test_exposed("forEach", Array.prototype, v >= 9);
     test_exposed("indexOf", Array.prototype, v >= 9);
     test_exposed("trim", String.prototype, v >= 9);
 
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 3e81961..928c558 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -90,6 +90,28 @@ function test_indexOf() {
     next_test();
 }
 
+function test_array_forEach() {
+    ok(Array.prototype.forEach.length === 1, "forEach.length = " + Array.prototype.forEach.length);
+
+    function test(array, expect) {
+        var r = Array.prototype.forEach.call(array, function(value, index, arr) {
+            ok(arr === array, "unexpected array " + arr);
+            ok(index === expect[0][0], "index = " + index + " expected " + expect[0][0]);
+            ok(value === expect[0][1], "value = " + value + " expected " + expect[0][1]);
+            expect.shift();
+        });
+        ok(r === undefined, "forEach returned " + r);
+        ok(expect.length === 0, "too few forEach() calls, expected " + expect.length + " more");
+    }
+
+    test(["a",2,"c"], [[0,"a"],[1,2],[2,"c"]]);
+    test({length: 1000, 500: false, c: 30, 3: "x", 999: 1}, [[3,"x"],[500,false],[999,1]]);
+    test(new String("abc"), [[0,"a"],[1,"b"],[2,"c"]]);
+    test([], []);
+
+    next_test();
+}
+
 function test_isArray() {
     function expect_array(a, exr) {
         var r = Array.isArray(a);
@@ -438,7 +460,6 @@ function test_property_definitions() {
         if(have_getter) {
             ok(typeof(desc.get) === "function", "desc.get = " + desc.get);
             ok(typeof(desc.get.prototype) === "object", "desc.get.prototype = " + desc.get.prototype);
-            trace("" + desc.get);
         }else {
             ok(!("get" in obj), "desc.get = " + desc.get);
         }
@@ -575,6 +596,7 @@ var tests = [
     test_date_now,
     test_toISOString,
     test_indexOf,
+    test_array_forEach,
     test_isArray,
     test_identifier_keywords,
     test_getOwnPropertyDescriptor,




More information about the wine-cvs mailing list