enhance reduce_vars (#5636)

This commit is contained in:
Alex Lam S.L
2022-08-30 09:00:43 +01:00
committed by GitHub
parent 15b608f74c
commit 10bc86ba10
7 changed files with 109 additions and 40 deletions

View File

@@ -621,8 +621,10 @@ Compressor.prototype.compress = function(node) {
scope.may_call_this = undefined;
}
function push(tw) {
tw.safe_ids = Object.create(tw.safe_ids);
function push(tw, sequential) {
var safe_ids = Object.create(tw.safe_ids);
if (!sequential) safe_ids.seq = {};
tw.safe_ids = safe_ids;
}
function pop(tw) {
@@ -643,7 +645,14 @@ Compressor.prototype.compress = function(node) {
var safe = tw.safe_ids[def.id];
if (safe) {
var in_order = HOP(tw.safe_ids, def.id);
if (!in_order) safe.read = safe.read && safe.read !== tw.safe_ids ? true : tw.safe_ids;
if (!in_order) {
var seq = tw.safe_ids.seq;
if (!safe.read) {
safe.read = seq;
} else if (safe.read !== seq) {
safe.read = true;
}
}
if (def.fixed == null) {
if (is_arguments(def)) return false;
if (def.global && def.name == "arguments") return false;
@@ -684,7 +693,7 @@ Compressor.prototype.compress = function(node) {
safe.assign = safe.assign && safe.assign !== tw.safe_ids ? true : tw.safe_ids;
}
if (def.fixed != null && safe.read) {
if (safe.read !== tw.safe_ids) return false;
if (safe.read !== tw.safe_ids.seq) return false;
if (tw.loop_ids[def.id] !== tw.in_loop) return false;
}
return safe_to_read(tw, def) && all(def.orig, function(sym) {
@@ -810,7 +819,7 @@ Compressor.prototype.compress = function(node) {
var scanner = new TreeWalker(function(node) {
if (node instanceof AST_DefaultValue) {
reset_flags(node);
push(tw);
push(tw, true);
node.value.walk(tw);
pop(tw);
var save = fixed;
@@ -899,14 +908,15 @@ Compressor.prototype.compress = function(node) {
var fn = this;
fn.inlined = false;
var iife = tw.parent();
var hit = is_async(fn) || is_generator(fn);
var sequential = !is_async(fn) && !is_generator(fn);
var hit = !sequential;
var aborts = false;
fn.walk(new TreeWalker(function(node) {
if (hit) return aborts = true;
if (node instanceof AST_Return) return hit = true;
if (node instanceof AST_Scope && node !== fn) return true;
}));
if (aborts) push(tw);
if (aborts) push(tw, sequential);
reset_variables(tw, compressor, fn);
// Virtually turn IIFE parameters into variable definitions:
// (function(a,b) {...})(c,d) ---> (function() {var a=c,b=d; ...})()
@@ -991,7 +1001,7 @@ Compressor.prototype.compress = function(node) {
return walk_lazy();
}
var safe = safe_to_read(tw, ld);
if (lazy) push(tw);
if (lazy) push(tw, true);
right.walk(tw);
if (lazy) pop(tw);
if (safe && !left.in_arg && safe_to_assign(tw, ld)) {
@@ -1073,7 +1083,7 @@ Compressor.prototype.compress = function(node) {
function walk_lazy() {
if (!lazy) return;
left.walk(tw);
push(tw);
push(tw, true);
right.walk(tw);
pop(tw);
return true;
@@ -1082,7 +1092,7 @@ Compressor.prototype.compress = function(node) {
def(AST_Binary, function(tw) {
if (!lazy_op[this.operator]) return;
this.left.walk(tw);
push(tw);
push(tw, true);
this.right.walk(tw);
pop(tw);
return true;
@@ -1112,7 +1122,7 @@ Compressor.prototype.compress = function(node) {
}
exp.walk(tw);
var optional = node.optional;
if (optional) push(tw);
if (optional) push(tw, true);
node.args.forEach(function(arg) {
arg.walk(tw);
});
@@ -1182,7 +1192,7 @@ Compressor.prototype.compress = function(node) {
});
def(AST_ClassInitBlock, function(tw, descend, compressor) {
var node = this;
push(tw);
push(tw, true);
reset_variables(tw, compressor, node);
descend();
pop_scope(tw, node);
@@ -1190,19 +1200,19 @@ Compressor.prototype.compress = function(node) {
});
def(AST_Conditional, function(tw) {
this.condition.walk(tw);
push(tw);
push(tw, true);
this.consequent.walk(tw);
pop(tw);
push(tw);
push(tw, true);
this.alternative.walk(tw);
pop(tw);
return true;
});
def(AST_DefaultValue, function(tw) {
this.name.walk(tw);
push(tw);
push(tw, true);
this.value.walk(tw);
pop(tw);
this.name.walk(tw);
return true;
});
def(AST_Do, function(tw) {
@@ -1274,18 +1284,18 @@ Compressor.prototype.compress = function(node) {
});
def(AST_If, function(tw) {
this.condition.walk(tw);
push(tw);
push(tw, true);
this.body.walk(tw);
pop(tw);
if (this.alternative) {
push(tw);
push(tw, true);
this.alternative.walk(tw);
pop(tw);
}
return true;
});
def(AST_LabeledStatement, function(tw) {
push(tw);
push(tw, true);
this.body.walk(tw);
pop(tw);
return true;
@@ -1319,7 +1329,7 @@ Compressor.prototype.compress = function(node) {
def(AST_Sub, function(tw) {
if (!this.optional) return;
this.expression.walk(tw);
push(tw);
push(tw, true);
this.property.walk(tw);
pop(tw);
return true;
@@ -1334,7 +1344,7 @@ Compressor.prototype.compress = function(node) {
branch.expression.walk(tw);
if (first) {
first = false;
push(tw);
push(tw, true);
}
})
if (!first) pop(tw);
@@ -1342,7 +1352,7 @@ Compressor.prototype.compress = function(node) {
return true;
});
def(AST_SwitchBranch, function(tw) {
push(tw);
push(tw, true);
walk_body(this, tw);
pop(tw);
return true;
@@ -1452,7 +1462,7 @@ Compressor.prototype.compress = function(node) {
node.globals.each(function(def) {
reset_def(tw, compressor, def);
});
push(tw);
push(tw, true);
reset_variables(tw, compressor, node);
descend();
pop_scope(tw, node);
@@ -1461,11 +1471,11 @@ Compressor.prototype.compress = function(node) {
def(AST_Try, function(tw, descend, compressor) {
var node = this;
reset_block_variables(tw, compressor, node);
push(tw);
push(tw, true);
walk_body(node, tw);
pop(tw);
if (node.bcatch) {
push(tw);
push(tw, true);
node.bcatch.walk(tw);
pop(tw);
}
@@ -1590,6 +1600,7 @@ Compressor.prototype.compress = function(node) {
// - `push()` & `pop()` when visiting conditional branches
// - backup & restore via `save_ids` when visiting out-of-order sections
tw.safe_ids = Object.create(null);
tw.safe_ids.seq = {};
this.walk(tw);
});
@@ -3524,6 +3535,7 @@ Compressor.prototype.compress = function(node) {
stat.alternative = make_node(AST_BlockStatement, stat, {
body: as_statement_array(stat.alternative).concat(extract_functions(merge_jump, jump)),
});
adjust_refs(ab.value, merge_jump);
statements[i] = stat;
statements[i] = stat.transform(compressor);
continue;
@@ -3563,6 +3575,7 @@ Compressor.prototype.compress = function(node) {
stat.alternative = make_node(AST_BlockStatement, stat.alternative, {
body: as_statement_array_with_return(stat.alternative, alt),
});
adjust_refs(alt.value, merge_jump);
statements[i] = stat;
statements[i] = stat.transform(compressor);
continue;
@@ -3776,6 +3789,37 @@ Compressor.prototype.compress = function(node) {
return body;
}
function adjust_refs(value, mode) {
if (!mode) return;
if (!value) return;
switch (mode) {
case 4:
return;
case 3:
case 2:
value = value.tail_node();
}
var fixed_by_id = new Dictionary();
value.walk(new TreeWalker(function(node) {
if (!(node instanceof AST_SymbolRef)) return;
var def = node.definition();
if (def.scope.resolve() !== scope) return;
var fixed = node.fixed;
if (!fixed || !fixed_by_id.has(def.id)) {
fixed_by_id.set(def.id, fixed);
} else if (fixed_by_id.get(def.id) !== fixed) {
fixed_by_id.set(def.id, false);
}
}));
if (fixed_by_id.size() > 0) jump.value.walk(new TreeWalker(function(node) {
if (!(node instanceof AST_SymbolRef)) return;
var def = node.definition();
var fixed = node.fixed;
if (!fixed || !fixed_by_id.has(def.id)) return;
if (fixed_by_id.get(def.id) !== fixed) node.fixed = false;
}));
}
function next_index(i) {
declare_only = true;
for (var j = i; ++j < statements.length;) {