@@ -354,6 +354,13 @@ merge(Compressor.prototype, {
|
|||||||
return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
|
return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cross_scope(def, sym) {
|
||||||
|
do {
|
||||||
|
if (def === sym) return false;
|
||||||
|
if (sym instanceof AST_Scope) return true;
|
||||||
|
} while (sym = sym.parent_scope);
|
||||||
|
}
|
||||||
|
|
||||||
(function(def) {
|
(function(def) {
|
||||||
def(AST_Node, noop);
|
def(AST_Node, noop);
|
||||||
|
|
||||||
@@ -506,6 +513,7 @@ merge(Compressor.prototype, {
|
|||||||
function ref_once(compressor, def) {
|
function ref_once(compressor, def) {
|
||||||
return compressor.option("unused")
|
return compressor.option("unused")
|
||||||
&& !def.scope.pinned()
|
&& !def.scope.pinned()
|
||||||
|
&& def.single_use !== false
|
||||||
&& def.references.length - def.recursive_refs == 1;
|
&& def.references.length - def.recursive_refs == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -840,11 +848,13 @@ merge(Compressor.prototype, {
|
|||||||
&& d.orig[0] instanceof AST_SymbolDefun) {
|
&& d.orig[0] instanceof AST_SymbolDefun) {
|
||||||
tw.loop_ids[d.id] = tw.in_loop;
|
tw.loop_ids[d.id] = tw.in_loop;
|
||||||
}
|
}
|
||||||
var value;
|
if (d.fixed === false) {
|
||||||
if (d.fixed === undefined || !safe_to_read(tw, d)) {
|
var redef = d.redefined();
|
||||||
|
if (redef && cross_scope(d.scope, this.scope)) redef.single_use = false;
|
||||||
|
} else if (d.fixed === undefined || !safe_to_read(tw, d)) {
|
||||||
d.fixed = false;
|
d.fixed = false;
|
||||||
} else if (d.fixed) {
|
} else if (d.fixed) {
|
||||||
value = this.fixed_value();
|
var value = this.fixed_value();
|
||||||
var recursive = recursive_ref(tw, d);
|
var recursive = recursive_ref(tw, d);
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
d.recursive_refs++;
|
d.recursive_refs++;
|
||||||
@@ -5140,13 +5150,6 @@ merge(Compressor.prototype, {
|
|||||||
return rhs.right;
|
return rhs.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cross_scope(def, sym) {
|
|
||||||
do {
|
|
||||||
if (def === sym) return false;
|
|
||||||
if (sym instanceof AST_Scope) return true;
|
|
||||||
} while (sym = sym.parent_scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
function scan_ref_scoped(node, descend, init) {
|
function scan_ref_scoped(node, descend, init) {
|
||||||
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
|
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
|
||||||
var def = node.left.definition();
|
var def = node.left.definition();
|
||||||
@@ -8310,13 +8313,6 @@ merge(Compressor.prototype, {
|
|||||||
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
|
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
function find_variable(compressor, name) {
|
|
||||||
var level = 0, node;
|
|
||||||
while (node = compressor.parent(level++)) {
|
|
||||||
if (node.variables) return node.find_variable(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OPT(AST_Undefined, function(self, compressor) {
|
OPT(AST_Undefined, function(self, compressor) {
|
||||||
if (compressor.option("unsafe_undefined")) {
|
if (compressor.option("unsafe_undefined")) {
|
||||||
var undef = find_scope(compressor).find_variable("undefined");
|
var undef = find_scope(compressor).find_variable("undefined");
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
} else if (name == "arguments" && sym.scope instanceof AST_Lambda) {
|
||||||
sym.scope.uses_arguments = true;
|
sym.scope.uses_arguments = true;
|
||||||
}
|
}
|
||||||
if (name == "eval") {
|
if (name == "eval") {
|
||||||
|
|||||||
@@ -7535,3 +7535,69 @@ global_assign: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4188_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
while (A)
|
||||||
|
var a = function() {}, b = a;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(function() {
|
||||||
|
return typeof a;
|
||||||
|
}(), typeof b);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
while (A)
|
||||||
|
var a = function() {}, b = a;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(function() {
|
||||||
|
return typeof a;
|
||||||
|
}(), typeof b);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "object undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4188_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(function() {
|
||||||
|
return typeof a;
|
||||||
|
}(), typeof b);
|
||||||
|
}
|
||||||
|
while (!console)
|
||||||
|
var a = function() {}, b = a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
throw 42;
|
||||||
|
} catch (a) {
|
||||||
|
console.log(function() {
|
||||||
|
return typeof a;
|
||||||
|
}(), typeof b);
|
||||||
|
}
|
||||||
|
while (!console)
|
||||||
|
var a = function() {}, b = a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "number undefined"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user