[PATCH 7/8] jscript: Implement Array.prototype.some.

Gabriel Ivăncescu gabrielopcode at gmail.com
Fri Apr 15 08:00:27 CDT 2022


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/jscript/array.c     | 67 ++++++++++++++++++++++++++++++++++++++++
 dlls/mshtml/tests/es5.js | 34 ++++++++++++++++++++
 2 files changed, 101 insertions(+)

diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index 17c2c6f..525b3a3 100644
--- a/dlls/jscript/array.c
+++ b/dlls/jscript/array.c
@@ -1448,6 +1448,72 @@ done:
     return hres;
 }
 
+static HRESULT Array_some(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
+        jsval_t *r)
+{
+    IDispatch *context_obj = NULL, *callback;
+    jsval_t value, args[3], res;
+    BOOL boolval, ret = FALSE;
+    unsigned length, i;
+    jsdisp_t *jsthis;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = get_length(ctx, vthis, &jsthis, &length);
+    if(FAILED(hres))
+        return hres;
+
+    /* FIXME: check IsCallable */
+    if(!argc || !is_object_instance(argv[0])) {
+        FIXME("Invalid arg %s\n", debugstr_jsval(argc ? argv[0] : jsval_undefined()));
+        hres = E_INVALIDARG;
+        goto done;
+    }
+    callback = get_object(argv[0]);
+
+    if(argc > 1 && !is_undefined(argv[1])) {
+        if(!is_object_instance(argv[1])) {
+            FIXME("Unsupported context this %s\n", debugstr_jsval(argv[1]));
+            hres = E_NOTIMPL;
+            goto done;
+        }
+        context_obj = get_object(argv[1]);
+    }
+
+    for(i = 0; i < length; i++) {
+        hres = jsdisp_get_idx(jsthis, i, &value);
+        if(FAILED(hres)) {
+            if(hres == DISP_E_UNKNOWNNAME)
+                continue;
+            goto done;
+        }
+        args[0] = value;
+        args[1] = jsval_number(i);
+        args[2] = jsval_obj(jsthis);
+        hres = disp_call_value(ctx, callback, context_obj, DISPATCH_METHOD, ARRAY_SIZE(args), args, &res);
+        jsval_release(value);
+        if(FAILED(hres))
+            goto done;
+
+        hres = to_boolean(res, &boolval);
+        jsval_release(res);
+        if(FAILED(hres))
+            goto done;
+        if(boolval) {
+            ret = TRUE;
+            break;
+        }
+    }
+
+    if(r)
+        *r = jsval_bool(ret);
+    hres = S_OK;
+done:
+    jsdisp_release(jsthis);
+    return hres;
+}
+
 /* ECMA-262 3rd Edition    15.4.4.13 */
 static HRESULT Array_unshift(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv,
         jsval_t *r)
@@ -1552,6 +1618,7 @@ static const builtin_prop_t Array_props[] = {
     {L"reverse",               Array_reverse,              PROPF_METHOD},
     {L"shift",                 Array_shift,                PROPF_METHOD},
     {L"slice",                 Array_slice,                PROPF_METHOD|2},
+    {L"some",                  Array_some,                 PROPF_METHOD|PROPF_ES5|1},
     {L"sort",                  Array_sort,                 PROPF_METHOD|1},
     {L"splice",                Array_splice,               PROPF_METHOD|2},
     {L"toLocaleString",        Array_toLocaleString,       PROPF_METHOD},
diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js
index 32b60c9..ceb9c4a 100644
--- a/dlls/mshtml/tests/es5.js
+++ b/dlls/mshtml/tests/es5.js
@@ -175,6 +175,40 @@ sync_test("filter", function() {
     test([true,"b",42,Math,arr[9],"c"], function(v) { return v; }, Object);
 });
 
+sync_test("every & some", function() {
+    ok(Array.prototype.every.length === 1, "every.length = " + Array.prototype.every.length);
+    ok(Array.prototype.some.length === 1, "some.length = " + Array.prototype.some.length);
+    var arr = ["foobar"];
+
+    function test(expect_every, expect_some, fn, expect_this) {
+        var cb = function(v, i, a) {
+            ok(a === arr, "unexpected array " + arr);
+            ok(v === arr[i], "value = " + v + ", expected " + arr[i]);
+            ok(this === (expect_this ? expect_this : window), "this = " + this + ", expected " + expect_this);
+            return fn(v);
+        };
+        r = expect_this ? Array.prototype.every.call(arr, cb, expect_this) : Array.prototype.every.call(arr, cb);
+        ok(r === expect_every, "'every' = " + r);
+        r = expect_this ? Array.prototype.some.call(arr, cb, expect_this) : Array.prototype.some.call(arr, cb);
+        ok(r === expect_some, "'some' = " + r);
+    }
+
+    delete arr[0];
+    test(true, false, function(v) { return false; });
+    test(true, false, function(v) { return true; });
+
+    arr = [1,"2",3];
+    test(true, true, function(v) { return true; });
+    test(true, true, function(v) { if(arr[1] === "2") delete arr[1]; return typeof v === "number"; });
+    test(true, true, function(v) { if(arr[arr.length - 1] !== "a") arr.push("a"); return typeof v === "number"; }, Object);
+    test(false, true, function(v) { return typeof v === "number"; }, Object);
+
+    arr = [0,null,undefined,false];
+    test(false, false, function(v) { return v; });
+    arr.push(1);
+    test(false, true, function(v) { return v; });
+});
+
 sync_test("forEach", function() {
     ok(Array.prototype.forEach.length === 1, "forEach.length = " + Array.prototype.forEach.length);
 
-- 
2.34.1




More information about the wine-devel mailing list