diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-05-06 23:18:55 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-06 23:18:55 +0800 |
commit | 2c7ee956fd829624cacfdbde43d74ee8d3bb5e82 (patch) | |
tree | 6569ffecf4748f7da96e34a268167eb319fb082c /lib | |
parent | ecf3563c45e7cbf58cc9b7528ee5804691420a60 (diff) | |
download | tracifyjs-2c7ee956fd829624cacfdbde43d74ee8d3bb5e82.tar.gz tracifyjs-2c7ee956fd829624cacfdbde43d74ee8d3bb5e82.zip |
fix `unsafe` on `evaluate` of `reduce_vars` (#1870)
Determine if variables with non-constant values can escape and be modified.
fixes #1865
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/lib/compress.js b/lib/compress.js index 63eaacad..919ee20f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -283,6 +283,14 @@ merge(Compressor.prototype, { if (d.fixed === undefined || !safe_to_read(d) || is_modified(node, 0, is_immutable(node.fixed_value()))) { 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; + } } } if (node instanceof AST_SymbolCatch) { @@ -482,6 +490,7 @@ merge(Compressor.prototype, { } function reset_def(def) { + def.escaped = false; if (!def.global || def.orig[0] instanceof AST_SymbolConst || compressor.toplevel(def)) { def.fixed = undefined; } else { @@ -1595,23 +1604,20 @@ merge(Compressor.prototype, { : ev(this.alternative, compressor); }); def(AST_SymbolRef, function(compressor){ - if (this._evaluating) throw def; + if (!compressor.option("reduce_vars") || this._evaluating) throw def; this._evaluating = true; try { var fixed = this.fixed_value(); - if (compressor.option("reduce_vars") && fixed) { - if (compressor.option("unsafe")) { - if (!HOP(fixed, "_evaluated")) { - fixed._evaluated = ev(fixed, compressor); - } - return fixed._evaluated; - } - return ev(fixed, compressor); - } + if (!fixed) throw def; + var value = ev(fixed, compressor); + if (!HOP(fixed, "_eval")) fixed._eval = function() { + return value; + }; + if (value && typeof value == "object" && this.definition().escaped) throw def; + return value; } finally { this._evaluating = false; } - throw def; }); def(AST_PropAccess, function(compressor){ if (compressor.option("unsafe")) { |