in-place tigten_body() (#2111)
By reducing copies of `AST_Node` arrays, we should be able to reduce: - memory pressure - potential bugs caused by multiple references in AST - duplicated executions of `OPT()`
This commit is contained in:
243
lib/compress.js
243
lib/compress.js
@@ -668,26 +668,24 @@ merge(Compressor.prototype, {
|
|||||||
var CHANGED, max_iter = 10;
|
var CHANGED, max_iter = 10;
|
||||||
do {
|
do {
|
||||||
CHANGED = false;
|
CHANGED = false;
|
||||||
statements = eliminate_spurious_blocks(statements);
|
eliminate_spurious_blocks(statements);
|
||||||
if (compressor.option("dead_code")) {
|
if (compressor.option("dead_code")) {
|
||||||
statements = eliminate_dead_code(statements, compressor);
|
eliminate_dead_code(statements, compressor);
|
||||||
}
|
}
|
||||||
if (compressor.option("if_return")) {
|
if (compressor.option("if_return")) {
|
||||||
statements = handle_if_return(statements, compressor);
|
handle_if_return(statements, compressor);
|
||||||
}
|
}
|
||||||
if (compressor.sequences_limit > 0) {
|
if (compressor.sequences_limit > 0) {
|
||||||
statements = sequencesize(statements, compressor);
|
sequencesize(statements, compressor);
|
||||||
}
|
}
|
||||||
if (compressor.option("join_vars")) {
|
if (compressor.option("join_vars")) {
|
||||||
statements = join_consecutive_vars(statements, compressor);
|
join_consecutive_vars(statements, compressor);
|
||||||
}
|
}
|
||||||
if (compressor.option("collapse_vars")) {
|
if (compressor.option("collapse_vars")) {
|
||||||
statements = collapse(statements, compressor);
|
collapse(statements, compressor);
|
||||||
}
|
}
|
||||||
} while (CHANGED && max_iter-- > 0);
|
} while (CHANGED && max_iter-- > 0);
|
||||||
|
|
||||||
return statements;
|
|
||||||
|
|
||||||
// Search from right to left for assignment-like expressions:
|
// Search from right to left for assignment-like expressions:
|
||||||
// - `var a = x;`
|
// - `var a = x;`
|
||||||
// - `a = x;`
|
// - `a = x;`
|
||||||
@@ -789,7 +787,6 @@ merge(Compressor.prototype, {
|
|||||||
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
|
if (replaced && !remove_candidate(candidate)) statements.splice(stat_index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return statements;
|
|
||||||
|
|
||||||
function extract_candidates(expr) {
|
function extract_candidates(expr) {
|
||||||
if (expr instanceof AST_Assign && !expr.left.has_side_effects(compressor)
|
if (expr instanceof AST_Assign && !expr.left.has_side_effects(compressor)
|
||||||
@@ -891,59 +888,60 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function eliminate_spurious_blocks(statements) {
|
function eliminate_spurious_blocks(statements) {
|
||||||
var seen_dirs = [];
|
var seen_dirs = [];
|
||||||
return statements.reduce(function(a, stat){
|
for (var i = 0; i < statements.length;) {
|
||||||
|
var stat = statements[i];
|
||||||
if (stat instanceof AST_BlockStatement) {
|
if (stat instanceof AST_BlockStatement) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
a.push.apply(a, eliminate_spurious_blocks(stat.body));
|
eliminate_spurious_blocks(stat.body);
|
||||||
|
[].splice.apply(statements, [i, 1].concat(stat.body));
|
||||||
|
i += stat.body.length;
|
||||||
} else if (stat instanceof AST_EmptyStatement) {
|
} else if (stat instanceof AST_EmptyStatement) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
|
statements.splice(i, 1);
|
||||||
} else if (stat instanceof AST_Directive) {
|
} else if (stat instanceof AST_Directive) {
|
||||||
if (seen_dirs.indexOf(stat.value) < 0) {
|
if (seen_dirs.indexOf(stat.value) < 0) {
|
||||||
a.push(stat);
|
i++;
|
||||||
seen_dirs.push(stat.value);
|
seen_dirs.push(stat.value);
|
||||||
} else {
|
} else {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
|
statements.splice(i, 1);
|
||||||
|
}
|
||||||
|
} else i++;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
a.push(stat);
|
|
||||||
}
|
}
|
||||||
return a;
|
|
||||||
}, []);
|
|
||||||
};
|
|
||||||
|
|
||||||
function handle_if_return(statements, compressor) {
|
function handle_if_return(statements, compressor) {
|
||||||
var self = compressor.self();
|
var self = compressor.self();
|
||||||
var multiple_if_returns = has_multiple_if_returns(statements);
|
var multiple_if_returns = has_multiple_if_returns(statements);
|
||||||
var in_lambda = self instanceof AST_Lambda;
|
var in_lambda = self instanceof AST_Lambda;
|
||||||
var ret = []; // Optimized statements, build from tail to front
|
for (var i = statements.length; --i >= 0;) {
|
||||||
loop: for (var i = statements.length; --i >= 0;) {
|
|
||||||
var stat = statements[i];
|
var stat = statements[i];
|
||||||
switch (true) {
|
var next = statements[i + 1];
|
||||||
case (in_lambda && stat instanceof AST_Return && !stat.value && ret.length == 0):
|
|
||||||
|
if (in_lambda && stat instanceof AST_Return && !stat.value && !next) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
// note, ret.length is probably always zero
|
statements.length--;
|
||||||
// because we drop unreachable code before this
|
continue;
|
||||||
// step. nevertheless, it's good to check.
|
}
|
||||||
continue loop;
|
|
||||||
case stat instanceof AST_If:
|
if (stat instanceof AST_If) {
|
||||||
var ab = aborts(stat.body);
|
var ab = aborts(stat.body);
|
||||||
if (can_merge_flow(ab)) {
|
if (can_merge_flow(ab)) {
|
||||||
if (ab.label) {
|
if (ab.label) {
|
||||||
remove(ab.label.thedef.references, ab);
|
remove(ab.label.thedef.references, ab);
|
||||||
}
|
}
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
var funs = extract_functions_from_statement_array(ret);
|
|
||||||
var body = as_statement_array_with_return(stat.body, ab);
|
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.condition = stat.condition.negate(compressor);
|
stat.condition = stat.condition.negate(compressor);
|
||||||
|
var body = as_statement_array_with_return(stat.body, ab);
|
||||||
stat.body = make_node(AST_BlockStatement, stat, {
|
stat.body = make_node(AST_BlockStatement, stat, {
|
||||||
body: as_statement_array(stat.alternative).concat(ret)
|
body: as_statement_array(stat.alternative).concat(extract_functions())
|
||||||
});
|
});
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat, {
|
stat.alternative = make_node(AST_BlockStatement, stat, {
|
||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
ret = [ stat.transform(compressor) ].concat(funs);
|
statements[i] = stat.transform(compressor);
|
||||||
continue loop;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ab = aborts(stat.alternative);
|
var ab = aborts(stat.alternative);
|
||||||
@@ -952,53 +950,52 @@ merge(Compressor.prototype, {
|
|||||||
remove(ab.label.thedef.references, ab);
|
remove(ab.label.thedef.references, ab);
|
||||||
}
|
}
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
var funs = extract_functions_from_statement_array(ret);
|
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.body = make_node(AST_BlockStatement, stat.body, {
|
stat.body = make_node(AST_BlockStatement, stat.body, {
|
||||||
body: as_statement_array(stat.body).concat(ret)
|
body: as_statement_array(stat.body).concat(extract_functions())
|
||||||
});
|
});
|
||||||
var body = as_statement_array_with_return(stat.alternative, ab);
|
var body = as_statement_array_with_return(stat.alternative, ab);
|
||||||
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
|
||||||
body: body
|
body: body
|
||||||
});
|
});
|
||||||
ret = [ stat.transform(compressor) ].concat(funs);
|
statements[i] = stat.transform(compressor);
|
||||||
continue loop;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat.body instanceof AST_Return) {
|
if (stat instanceof AST_If && stat.body instanceof AST_Return) {
|
||||||
var value = stat.body.value;
|
var value = stat.body.value;
|
||||||
//---
|
//---
|
||||||
// pretty silly case, but:
|
// pretty silly case, but:
|
||||||
// if (foo()) return; return; ==> foo(); return;
|
// if (foo()) return; return; ==> foo(); return;
|
||||||
if ((in_lambda && ret.length == 0 || ret[0] instanceof AST_Return && !ret[0].value)
|
if (!value && !stat.alternative
|
||||||
&& !value && !stat.alternative) {
|
&& (in_lambda && !next || next instanceof AST_Return && !next.value)) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
var cond = make_node(AST_SimpleStatement, stat.condition, {
|
statements[i] = make_node(AST_SimpleStatement, stat.condition, {
|
||||||
body: stat.condition
|
body: stat.condition
|
||||||
});
|
});
|
||||||
ret.unshift(cond);
|
continue;
|
||||||
continue loop;
|
|
||||||
}
|
}
|
||||||
//---
|
//---
|
||||||
// if (foo()) return x; return y; ==> return foo() ? x : y;
|
// if (foo()) return x; return y; ==> return foo() ? x : y;
|
||||||
if (ret[0] instanceof AST_Return && value && ret[0].value && !stat.alternative) {
|
if (value && !stat.alternative && next instanceof AST_Return && next.value) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.alternative = ret[0];
|
stat.alternative = next;
|
||||||
ret[0] = stat.transform(compressor);
|
statements.splice(i, 2, stat.transform(compressor));
|
||||||
continue loop;
|
continue;
|
||||||
}
|
}
|
||||||
//---
|
//---
|
||||||
// if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
|
// if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
|
||||||
if (multiple_if_returns && (ret.length == 0 || ret[0] instanceof AST_Return)
|
if (multiple_if_returns && in_lambda && value && !stat.alternative
|
||||||
&& value && !stat.alternative && in_lambda) {
|
&& (!next || next instanceof AST_Return)) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.alternative = ret[0] || make_node(AST_Return, stat, {
|
stat.alternative = next || make_node(AST_Return, stat, {
|
||||||
value: null
|
value: null
|
||||||
});
|
});
|
||||||
ret[0] = stat.transform(compressor);
|
statements.splice(i, next ? 2 : 1, stat.transform(compressor));
|
||||||
continue loop;
|
continue;
|
||||||
}
|
}
|
||||||
//---
|
//---
|
||||||
// if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
|
// if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
|
||||||
@@ -1006,27 +1003,18 @@ merge(Compressor.prototype, {
|
|||||||
// if sequences is not enabled, this can lead to an endless loop (issue #866).
|
// if sequences is not enabled, this can lead to an endless loop (issue #866).
|
||||||
// however, with sequences on this helps producing slightly better output for
|
// however, with sequences on this helps producing slightly better output for
|
||||||
// the example code.
|
// the example code.
|
||||||
if (compressor.option("sequences")
|
var prev = statements[i - 1];
|
||||||
&& i > 0 && statements[i - 1] instanceof AST_If && statements[i - 1].body instanceof AST_Return
|
if (compressor.option("sequences") && in_lambda && !stat.alternative
|
||||||
&& ret.length == 1 && in_lambda && ret[0] instanceof AST_SimpleStatement
|
&& prev instanceof AST_If && prev.body instanceof AST_Return
|
||||||
&& !stat.alternative) {
|
&& i + 2 == statements.length && next instanceof AST_SimpleStatement) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
ret.push(make_node(AST_Return, ret[0], {
|
statements.push(make_node(AST_Return, next, {
|
||||||
value: null
|
value: null
|
||||||
}).transform(compressor));
|
}).transform(compressor));
|
||||||
ret.unshift(stat);
|
continue;
|
||||||
continue loop;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.unshift(stat);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret.unshift(stat);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
function has_multiple_if_returns(statements) {
|
function has_multiple_if_returns(statements) {
|
||||||
var n = 0;
|
var n = 0;
|
||||||
@@ -1051,6 +1039,18 @@ merge(Compressor.prototype, {
|
|||||||
|| ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct;
|
|| ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extract_functions() {
|
||||||
|
var tail = statements.slice(i + 1);
|
||||||
|
statements.length = i + 1;
|
||||||
|
return tail.filter(function(stat) {
|
||||||
|
if (stat instanceof AST_Defun) {
|
||||||
|
statements.push(stat);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function as_statement_array_with_return(node, ab) {
|
function as_statement_array_with_return(node, ab) {
|
||||||
var body = as_statement_array(node).slice(0, -1);
|
var body = as_statement_array(node).slice(0, -1);
|
||||||
if (ab.value) {
|
if (ab.value) {
|
||||||
@@ -1060,49 +1060,52 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function eliminate_dead_code(statements, compressor) {
|
function eliminate_dead_code(statements, compressor) {
|
||||||
var has_quit = false;
|
var has_quit;
|
||||||
var orig = statements.length;
|
|
||||||
var self = compressor.self();
|
var self = compressor.self();
|
||||||
statements = statements.reduce(function(a, stat){
|
for (var i = 0, n = 0, len = statements.length; i < len; i++) {
|
||||||
if (has_quit) {
|
var stat = statements[i];
|
||||||
extract_declarations_from_unreachable_code(compressor, stat, a);
|
|
||||||
} else {
|
|
||||||
if (stat instanceof AST_LoopControl) {
|
if (stat instanceof AST_LoopControl) {
|
||||||
var lct = compressor.loopcontrol_target(stat);
|
var lct = compressor.loopcontrol_target(stat);
|
||||||
if ((stat instanceof AST_Break
|
if (stat instanceof AST_Break
|
||||||
&& !(lct instanceof AST_IterationStatement)
|
&& !(lct instanceof AST_IterationStatement)
|
||||||
&& loop_body(lct) === self) || (stat instanceof AST_Continue
|
&& loop_body(lct) === self
|
||||||
&& loop_body(lct) === self)) {
|
|| stat instanceof AST_Continue
|
||||||
|
&& loop_body(lct) === self) {
|
||||||
if (stat.label) {
|
if (stat.label) {
|
||||||
remove(stat.label.thedef.references, stat);
|
remove(stat.label.thedef.references, stat);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
a.push(stat);
|
statements[n++] = stat;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
a.push(stat);
|
statements[n++] = stat;
|
||||||
}
|
}
|
||||||
if (aborts(stat)) has_quit = true;
|
if (aborts(stat)) {
|
||||||
|
has_quit = statements.slice(i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statements.length = n;
|
||||||
|
CHANGED = n != len;
|
||||||
|
if (has_quit) has_quit.forEach(function(stat) {
|
||||||
|
extract_declarations_from_unreachable_code(compressor, stat, statements);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return a;
|
|
||||||
}, []);
|
|
||||||
CHANGED = statements.length != orig;
|
|
||||||
return statements;
|
|
||||||
};
|
|
||||||
|
|
||||||
function sequencesize(statements, compressor) {
|
function sequencesize(statements, compressor) {
|
||||||
if (statements.length < 2) return statements;
|
if (statements.length < 2) return;
|
||||||
var seq = [], ret = [];
|
var seq = [], n = 0;
|
||||||
function push_seq() {
|
function push_seq() {
|
||||||
if (!seq.length) return;
|
if (!seq.length) return;
|
||||||
var body = make_sequence(seq[0], seq);
|
var body = make_sequence(seq[0], seq);
|
||||||
ret.push(make_node(AST_SimpleStatement, body, { body: body }));
|
statements[n++] = make_node(AST_SimpleStatement, body, { body: body });
|
||||||
seq = [];
|
seq = [];
|
||||||
};
|
}
|
||||||
statements.forEach(function(stat){
|
for (var i = 0, len = statements.length; i < len; i++) {
|
||||||
|
var stat = statements[i];
|
||||||
if (stat instanceof AST_SimpleStatement) {
|
if (stat instanceof AST_SimpleStatement) {
|
||||||
if (seq.length >= compressor.sequences_limit) push_seq();
|
if (seq.length >= compressor.sequences_limit) push_seq();
|
||||||
var body = stat.body;
|
var body = stat.body;
|
||||||
@@ -1110,18 +1113,18 @@ merge(Compressor.prototype, {
|
|||||||
if (body) merge_sequence(seq, body);
|
if (body) merge_sequence(seq, body);
|
||||||
} else {
|
} else {
|
||||||
push_seq();
|
push_seq();
|
||||||
ret.push(stat);
|
statements[n++] = stat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
push_seq();
|
push_seq();
|
||||||
ret = sequencesize_2(ret, compressor);
|
statements.length = n;
|
||||||
CHANGED = ret.length != statements.length;
|
sequencesize_2(statements, compressor);
|
||||||
return ret;
|
CHANGED = statements.length != len;
|
||||||
};
|
}
|
||||||
|
|
||||||
function sequencesize_2(statements, compressor) {
|
function sequencesize_2(statements, compressor) {
|
||||||
function cons_seq(right) {
|
function cons_seq(right) {
|
||||||
ret.pop();
|
n--;
|
||||||
var left = prev.body;
|
var left = prev.body;
|
||||||
if (!(left instanceof AST_Sequence)) {
|
if (!(left instanceof AST_Sequence)) {
|
||||||
left = make_node(AST_Sequence, left, {
|
left = make_node(AST_Sequence, left, {
|
||||||
@@ -1131,8 +1134,9 @@ merge(Compressor.prototype, {
|
|||||||
merge_sequence(left.expressions, right);
|
merge_sequence(left.expressions, right);
|
||||||
return left.transform(compressor);
|
return left.transform(compressor);
|
||||||
};
|
};
|
||||||
var ret = [], prev = null;
|
var n = 0, prev;
|
||||||
statements.forEach(function(stat){
|
for (var i = 0, len = statements.length; i < len; i++) {
|
||||||
|
var stat = statements[i];
|
||||||
if (prev) {
|
if (prev) {
|
||||||
if (stat instanceof AST_For) {
|
if (stat instanceof AST_For) {
|
||||||
try {
|
try {
|
||||||
@@ -1145,7 +1149,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
else if (!stat.init) {
|
else if (!stat.init) {
|
||||||
stat.init = prev.body.drop_side_effect_free(compressor);
|
stat.init = prev.body.drop_side_effect_free(compressor);
|
||||||
ret.pop();
|
n--;
|
||||||
}
|
}
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
if (ex !== cons_seq) throw ex;
|
if (ex !== cons_seq) throw ex;
|
||||||
@@ -1167,15 +1171,16 @@ merge(Compressor.prototype, {
|
|||||||
stat.expression = cons_seq(stat.expression);
|
stat.expression = cons_seq(stat.expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret.push(stat);
|
statements[n++] = stat;
|
||||||
prev = stat instanceof AST_SimpleStatement ? stat : null;
|
prev = stat instanceof AST_SimpleStatement ? stat : null;
|
||||||
});
|
}
|
||||||
return ret;
|
statements.length = n;
|
||||||
};
|
}
|
||||||
|
|
||||||
function join_consecutive_vars(statements, compressor) {
|
function join_consecutive_vars(statements, compressor) {
|
||||||
var prev = null;
|
for (var i = 0, j = -1, len = statements.length; i < len; i++) {
|
||||||
return statements.reduce(function(a, stat){
|
var stat = statements[i];
|
||||||
|
var prev = statements[j];
|
||||||
if (stat instanceof AST_Definitions && prev && prev.TYPE == stat.TYPE) {
|
if (stat instanceof AST_Definitions && prev && prev.TYPE == stat.TYPE) {
|
||||||
prev.definitions = prev.definitions.concat(stat.definitions);
|
prev.definitions = prev.definitions.concat(stat.definitions);
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
@@ -1184,35 +1189,19 @@ merge(Compressor.prototype, {
|
|||||||
&& prev instanceof AST_Var
|
&& prev instanceof AST_Var
|
||||||
&& (!stat.init || stat.init.TYPE == prev.TYPE)) {
|
&& (!stat.init || stat.init.TYPE == prev.TYPE)) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
a.pop();
|
|
||||||
if (stat.init) {
|
if (stat.init) {
|
||||||
stat.init.definitions = prev.definitions.concat(stat.init.definitions);
|
stat.init.definitions = prev.definitions.concat(stat.init.definitions);
|
||||||
} else {
|
} else {
|
||||||
stat.init = prev;
|
stat.init = prev;
|
||||||
}
|
}
|
||||||
a.push(stat);
|
statements[j] = stat;
|
||||||
prev = stat;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prev = stat;
|
statements[++j] = stat;
|
||||||
a.push(stat);
|
|
||||||
}
|
}
|
||||||
return a;
|
}
|
||||||
}, []);
|
statements.length = j + 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
function extract_functions_from_statement_array(statements) {
|
|
||||||
var funs = [];
|
|
||||||
for (var i = statements.length - 1; i >= 0; --i) {
|
|
||||||
var stat = statements[i];
|
|
||||||
if (stat instanceof AST_Defun) {
|
|
||||||
statements.splice(i, 1);
|
|
||||||
funs.unshift(stat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return funs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function extract_declarations_from_unreachable_code(compressor, stat, target) {
|
function extract_declarations_from_unreachable_code(compressor, stat, target) {
|
||||||
@@ -1989,12 +1978,12 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Block, function(self, compressor){
|
OPT(AST_Block, function(self, compressor){
|
||||||
self.body = tighten_body(self.body, compressor);
|
tighten_body(self.body, compressor);
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_BlockStatement, function(self, compressor){
|
OPT(AST_BlockStatement, function(self, compressor){
|
||||||
self.body = tighten_body(self.body, compressor);
|
tighten_body(self.body, compressor);
|
||||||
switch (self.body.length) {
|
switch (self.body.length) {
|
||||||
case 1: return self.body[0];
|
case 1: return self.body[0];
|
||||||
case 0: return make_node(AST_EmptyStatement, self);
|
case 0: return make_node(AST_EmptyStatement, self);
|
||||||
@@ -2901,7 +2890,7 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Try, function(self, compressor){
|
OPT(AST_Try, function(self, compressor){
|
||||||
self.body = tighten_body(self.body, compressor);
|
tighten_body(self.body, compressor);
|
||||||
if (self.bcatch && self.bfinally && all(self.bfinally.body, is_empty)) self.bfinally = null;
|
if (self.bcatch && self.bfinally && all(self.bfinally.body, is_empty)) self.bfinally = null;
|
||||||
if (all(self.body, is_empty)) {
|
if (all(self.body, is_empty)) {
|
||||||
var body = [];
|
var body = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user