Module: wine Branch: master Commit: cda846b8cbc39c07ce360a6660a1c8b2e2aca24b URL: https://source.winehq.org/git/wine.git/?a=commit;h=cda846b8cbc39c07ce360a666...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Dec 5 20:42:27 2018 +0100
jscript: Add Array.prototype.forEach implementation.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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,