aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-12-29 16:22:03 +0000
committerGitHub <noreply@github.com>2020-12-30 00:22:03 +0800
commit1956edd503bde9db8e99d8a499d54d5a508f8bb8 (patch)
tree32b1f05ad7820a1070639ef78ae5caf4fcfd0ac9
parent560ccc1221639dca9db354ad6830e418a9f0073d (diff)
downloadtracifyjs-1956edd503bde9db8e99d8a499d54d5a508f8bb8.tar.gz
tracifyjs-1956edd503bde9db8e99d8a499d54d5a508f8bb8.zip
fix corner cases with `arguments` (#4481)
fixes #4480
-rw-r--r--lib/compress.js5
-rw-r--r--lib/scope.js18
-rw-r--r--test/compress/arguments.js17
-rw-r--r--test/compress/evaluate.js25
-rw-r--r--test/compress/keep_fargs.js50
5 files changed, 56 insertions, 59 deletions
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,