Module: wine Branch: master Commit: 59372aa98c981959299105a4eec32ea3595afab4 URL: https://gitlab.winehq.org/wine/wine/-/commit/59372aa98c981959299105a4eec32ea...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Wed Jun 21 17:58:01 2023 +0300
jscript: Start from the last argument when adding them to named locals.
This is needed for duplicated argument names, as the last arg will shadow all the prior ones when it comes to name lookup.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/jscript/compile.c | 2 +- dlls/jscript/tests/lang.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index e2690935212..2d2c2c9f40a 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -2567,7 +2567,7 @@ static HRESULT compile_function(compiler_ctx_t *ctx, statement_t *source, functi } }
- for(i = 0; i < func->param_cnt; i++) { + for(i = func->param_cnt; i--;) { if(!find_local(ctx, func->params[i], 0) && !alloc_local(ctx, func->params[i], -i-1, 0)) return E_OUTOFMEMORY; } diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index 5c201d5bf26..30d8a338fd3 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -306,6 +306,38 @@ argumentsTest(); ok(arguments === 1, "arguments = " + arguments); })();
+// duplicated argument names are shadowed by the last argument with the same name +(function() { + var args, get_a, set_a; + + (function(a, a, b, c) { + get_a = function() { return a; } + set_a = function(v) { a = v; } + ok(get_a() === 2, "function(a, a, b, c) get_a() = " + get_a()); + ok(a === 2, "function(a, a, b, c) a = " + a); + ok(b === 3, "function(a, a, b, c) b = " + b); + ok(c === 4, "function(a, a, b, c) c = " + c); + a = 42; + ok(arguments[0] === 1, "function(a, a, b, c) arguments[0] = " + arguments[0]); + ok(arguments[1] === 42, "function(a, a, b, c) arguments[1] = " + arguments[1]); + ok(get_a() === 42, "function(a, a, b, c) get_a() = " + get_a() + " expected 42"); + args = arguments; + })(1, 2, 3, 4); + + ok(get_a() === 42, "function(a, a, b, c) get_a() after detach = " + get_a()); + set_a(100); + ok(get_a() === 100, "function(a, a, b, c) get_a() = " + get_a() + " expected 100"); + ok(args[0] === 1, "function(a, a, b, c) detached args[0] = " + args[0]); + ok(args[1] === 42, "function(a, a, b, c) detached args[1] = " + args[1]); + + (function(a, a) { + eval("var a = 7;"); + ok(a === 7, "function(a, a) a = " + a); + ok(arguments[0] === 5, "function(a, a) arguments[0] = " + arguments[0]); + ok(arguments[1] === 7, "function(a, a) arguments[1] = " + arguments[1]); + })(5, 6); +})(); + (function callAsExprTest() { ok(callAsExprTest.arguments === null, "callAsExprTest.arguments = " + callAsExprTest.arguments); })(1,2);