From: Alex Lam S.L Date: Tue, 29 Dec 2020 16:22:03 +0000 (+0000) Subject: fix corner cases with `arguments` (#4481) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1956edd503bde9db8e99d8a499d54d5a508f8bb8;p=UglifyJS.git fix corner cases with `arguments` (#4481) fixes #4480 --- diff --git a/lib/compress.js b/lib/compress.js index 591ad4dd..3ac9e74d 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -357,10 +357,7 @@ merge(Compressor.prototype, { } function is_arguments(def) { - if (def.name != "arguments") return false; - if (!def.scope.uses_arguments) return false; - var orig = def.orig; - return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg; + return def.name == "arguments" && def.scope.uses_arguments; } function is_funarg(def) { diff --git a/lib/scope.js b/lib/scope.js index 0c35b0dd..4660c787 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -265,10 +265,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } if (!sym) { sym = self.def_global(node); - } else if (name == "arguments" - && sym.orig[0] instanceof AST_SymbolFunarg - && !(sym.orig[1] instanceof AST_SymbolFunarg) - && !(sym.scope instanceof AST_Arrow)) { + } else if (name == "arguments" && is_arguments(sym)) { var parent = tw.parent(); if (parent instanceof AST_Assign && parent.left === node || parent instanceof AST_Unary && unary_side_effects[parent.operator]) { @@ -297,6 +294,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { node.reference(options); return true; } + if (node instanceof AST_VarDef) { + if (node.value && node.name.name == "arguments") { + var sym = node.name.scope.resolve().find_variable("arguments"); + if (sym && is_arguments(sym)) sym.scope.uses_arguments = 3; + } + return; + } }); self.walk(tw); @@ -322,6 +326,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) { } })); + function is_arguments(sym) { + return sym.orig[0] instanceof AST_SymbolFunarg + && !(sym.orig[1] instanceof AST_SymbolFunarg || sym.orig[2] instanceof AST_SymbolFunarg) + && !(sym.scope instanceof AST_Arrow); + } + function redefine(node, scope) { var name = node.name; var old_def = node.thedef; diff --git a/test/compress/arguments.js b/test/compress/arguments.js index 3ca244af..655d75a4 100644 --- a/test/compress/arguments.js +++ b/test/compress/arguments.js @@ -101,6 +101,13 @@ replace_index_drop_fargs_1: { var arguments; console.log(arguments[1], arguments["1"], arguments["foo"]); })("bar", 42); + (function() { + var arguments = { + 1: "foo", + foo: "bar", + }; + console.log(arguments[1], arguments["1"], arguments["foo"]); + })("bar", 42); } expect: { var arguments = []; @@ -114,8 +121,15 @@ replace_index_drop_fargs_1: { (function(arguments) { console.log(arguments[1], arguments[1], arguments.foo); })("bar", 42); - (function() { + (function(argument_0, argument_1) { var arguments; + console.log(argument_1, argument_1, arguments.foo); + })("bar", 42); + (function() { + var arguments = { + 1: "foo", + foo: "bar", + }; console.log(arguments[1], arguments[1], arguments.foo); })("bar", 42); } @@ -125,6 +139,7 @@ replace_index_drop_fargs_1: { "42 42 undefined", "a a undefined", "42 42 undefined", + "foo foo bar", ] } diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 7466d63b..73c982f2 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -3117,3 +3117,28 @@ issue_4422: { } expect_stdout: "PASS" } + +issue_4480: { + options = { + evaluate: true, + reduce_vars: true, + unused: true, + } + input: { + var a = function f(b) { + b = "FAIL"; + arguments[0] = "PASS"; + var arguments = 0; + console.log(b); + }(a); + } + expect: { + var a = function(b) { + b = "FAIL"; + arguments[0] = "PASS"; + var arguments = 0; + console.log(b); + }(a); + } + expect_stdout: "PASS" +} diff --git a/test/compress/keep_fargs.js b/test/compress/keep_fargs.js index 049684a7..d5d7ef93 100644 --- a/test/compress/keep_fargs.js +++ b/test/compress/keep_fargs.js @@ -80,56 +80,6 @@ keep_fargs_true: { ] } -replace_index: { - options = { - arguments: true, - evaluate: true, - keep_fargs: false, - properties: true, - } - input: { - var arguments = []; - console.log(arguments[0]); - (function() { - console.log(arguments[1], arguments["1"], arguments["foo"]); - })("bar", 42); - (function(a, b) { - console.log(arguments[1], arguments["1"], arguments["foo"]); - })("bar", 42); - (function(arguments) { - console.log(arguments[1], arguments["1"], arguments["foo"]); - })("bar", 42); - (function() { - var arguments; - console.log(arguments[1], arguments["1"], arguments["foo"]); - })("bar", 42); - } - expect: { - var arguments = []; - console.log(arguments[0]); - (function(argument_0, argument_1) { - console.log(argument_1, argument_1, arguments.foo); - })("bar", 42); - (function(a, b) { - console.log(b, b, arguments.foo); - })("bar", 42); - (function(arguments) { - console.log(arguments[1], arguments[1], arguments.foo); - })("bar", 42); - (function() { - var arguments; - console.log(arguments[1], arguments[1], arguments.foo); - })("bar", 42); - } - expect_stdout: [ - "undefined", - "42 42 undefined", - "42 42 undefined", - "a a undefined", - "42 42 undefined", - ] -} - replace_index_strict: { options = { arguments: true,