aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-06-06 10:04:37 +0800
committerGitHub <noreply@github.com>2020-06-06 10:04:37 +0800
commit486ce00b8ea879f1bd05a07033b6098cbde6facf (patch)
tree3bdfc8dc2a2676fd0448d466596f545882976695
parenteb481cee8cebcb0bee778827cab6d625e5cb30b8 (diff)
downloadtracifyjs-486ce00b8ea879f1bd05a07033b6098cbde6facf.tar.gz
tracifyjs-486ce00b8ea879f1bd05a07033b6098cbde6facf.zip
fix corner case in `reduce_vars` (#3959)
fixes #3958
-rw-r--r--lib/compress.js50
-rw-r--r--test/compress/reduce_vars.js35
2 files changed, 62 insertions, 23 deletions
diff --git a/lib/compress.js b/lib/compress.js
index db445bbc..f71d9568 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -352,6 +352,23 @@ merge(Compressor.prototype, {
return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
}
+ function is_content_constant(ref, depth) {
+ var escaped = ref.definition().escaped;
+ switch (escaped.length) {
+ case 0:
+ return true;
+ case 1:
+ var found = false;
+ escaped[0].walk(new TreeWalker(function(node) {
+ if (found) return true;
+ if (node === ref) return found = true;
+ }));
+ return found;
+ default:
+ return depth <= escaped.depth;
+ }
+ }
+
(function(def) {
def(AST_Node, noop);
@@ -496,9 +513,15 @@ merge(Compressor.prototype, {
}
function to_value(def, sym, fixed) {
- if (fixed instanceof AST_Node) return fixed;
- if (typeof fixed == "function") return fixed();
- return make_node(AST_Undefined, sym);
+ if (fixed == null) {
+ fixed = make_node(AST_Undefined, sym);
+ } else if (typeof fixed == "function") {
+ fixed = fixed();
+ }
+ if (fixed instanceof AST_Array || fixed instanceof AST_Object) {
+ if (!is_content_constant(sym)) return false;
+ }
+ return fixed;
}
function ref_once(compressor, def) {
@@ -3515,27 +3538,8 @@ merge(Compressor.prototype, {
};
cached.push(fixed);
}
- if (value && typeof value == "object") {
- var escaped = this.definition().escaped;
- switch (escaped.length) {
- case 0:
- break;
- case 1:
- if (contains_ref(escaped[0], this)) break;
- default:
- if (depth > escaped.depth) return this;
- }
- }
+ if (value && typeof value == "object" && !is_content_constant(this, depth)) return this;
return value;
-
- function contains_ref(expr, ref) {
- var found = false;
- expr.walk(new TreeWalker(function(node) {
- if (found) return true;
- if (node === ref) return found = true;
- }));
- return found;
- }
});
var global_objs = {
Array: Array,
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index 1a782b44..41eb0096 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -7323,3 +7323,38 @@ issue_3957_2: {
"0",
]
}
+
+issue_3958: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ side_effects: true,
+ toplevel: true,
+ unsafe: true,
+ unused: true,
+ }
+ input: {
+ var a;
+ (function(b) {
+ (function(c) {
+ console.log(c[0] = 1);
+ })(a = b);
+ --a;
+ })([]);
+ console.log(a);
+ }
+ expect: {
+ var a;
+ (function(b) {
+ (function(c) {
+ console.log(c[0] = 1);
+ })(a = []);
+ --a;
+ })();
+ console.log(a);
+ }
+ expect_stdout: [
+ "1",
+ "0",
+ ]
+}