From: Alex Lam S.L Date: Sat, 21 Oct 2017 19:23:31 +0000 (+0800) Subject: fix `unsafe` escape analysis in `reduce_vars` (#2387) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=011123223b8e45ab3f6d151ad038a6b8ecec2434;p=UglifyJS.git fix `unsafe` escape analysis in `reduce_vars` (#2387) --- diff --git a/lib/compress.js b/lib/compress.js index 1f58b390..c7e08638 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -327,13 +327,7 @@ merge(Compressor.prototype, { d.fixed = false; } } else { - var parent = tw.parent(); - if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right - || parent instanceof AST_Call && node !== parent.expression - || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope - || parent instanceof AST_VarDef && node === parent.value) { - d.escaped = true; - } + mark_escaped(d, node, 0); } } } @@ -579,6 +573,18 @@ merge(Compressor.prototype, { return !immutable && is_modified(parent, level + 1); } } + + function mark_escaped(d, node, level) { + var parent = tw.parent(level); + if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right + || parent instanceof AST_Call && node !== parent.expression + || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope + || parent instanceof AST_VarDef && node === parent.value) { + d.escaped = true; + } else if (parent instanceof AST_PropAccess && node === parent.expression) { + mark_escaped(d, parent, level + 1); + } + } }); AST_SymbolRef.DEFMETHOD("fixed_value", function() { diff --git a/test/compress/arrays.js b/test/compress/arrays.js index f0ded06c..539dfb04 100644 --- a/test/compress/arrays.js +++ b/test/compress/arrays.js @@ -128,50 +128,55 @@ constant_join_3: { for_loop: { options = { - unsafe : true, - unused : true, - evaluate : true, - reduce_vars : true + evaluate: true, + reduce_vars: true, + unsafe: true, }; input: { function f0() { var a = [1, 2, 3]; - for (var i = 0; i < a.length; i++) { - console.log(a[i]); - } + var b = 0; + for (var i = 0; i < a.length; i++) + b += a[i]; + return b; } - function f1() { var a = [1, 2, 3]; - for (var i = 0, len = a.length; i < len; i++) { - console.log(a[i]); - } + var b = 0; + for (var i = 0, len = a.length; i < len; i++) + b += a[i]; + return b; } - function f2() { var a = [1, 2, 3]; - for (var i = 0; i < a.length; i++) { + for (var i = 0; i < a.length; i++) a[i]++; - } + return a[2]; } + console.log(f0(), f1(), f2()); } expect: { function f0() { var a = [1, 2, 3]; + var b = 0; for (var i = 0; i < 3; i++) - console.log(a[i]); + b += a[i]; + return b; } - function f1() { var a = [1, 2, 3]; - for (var i = 0; i < 3; i++) - console.log(a[i]); + var b = 0; + for (var i = 0, len = a.length; i < len; i++) + b += a[i]; + return b; } - function f2() { var a = [1, 2, 3]; for (var i = 0; i < a.length; i++) a[i]++; + return a[2]; } + console.log(f0(), f1(), f2()); } + expect_stdout: "6 6 4" } diff --git a/test/compress/functions.js b/test/compress/functions.js index f411afa2..6c82557d 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -151,13 +151,13 @@ issue_1841_2: { function_returning_constant_literal: { options = { + inline: true, + passes: 2, reduce_vars: true, - unsafe: true, + side_effects: true, toplevel: true, - evaluate: true, - cascade: true, + unsafe: true, unused: true, - inline: true, } input: { function greeter() { diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index a03bc1c8..681dafd3 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -2954,3 +2954,32 @@ const_expr_2: { } expect_stdout: "2 2" } + +escaped_prop: { + options = { + collapse_vars: true, + evaluate: true, + inline: true, + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + toplevel: true, + unsafe: true, + unused: true, + } + input: { + var obj = { o: { a: 1 } }; + (function(o) { + o.a++; + })(obj.o); + (function(o) { + console.log(o.a); + })(obj.o); + } + expect: { + var obj = { o: { a: 1 } }; + obj.o.a++; + console.log(obj.o.a); + } + expect_stdout: "2" +}