enhance merge_vars (#4125)
This commit is contained in:
@@ -4322,7 +4322,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
AST_Scope.DEFMETHOD("merge_variables", function(compressor) {
|
AST_Scope.DEFMETHOD("merge_variables", function(compressor) {
|
||||||
if (!compressor.option("merge_vars")) return;
|
if (!compressor.option("merge_vars")) return;
|
||||||
var self = this, segment = null;
|
var self = this, segment = {};
|
||||||
var first = [], last = [], index = 0;
|
var first = [], last = [], index = 0;
|
||||||
var declarations = new Dictionary();
|
var declarations = new Dictionary();
|
||||||
var references = Object.create(null);
|
var references = Object.create(null);
|
||||||
@@ -4331,9 +4331,9 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_Assign) {
|
if (node instanceof AST_Assign) {
|
||||||
var sym = node.left;
|
var sym = node.left;
|
||||||
if (!(sym instanceof AST_SymbolRef)) return;
|
if (!(sym instanceof AST_SymbolRef)) return;
|
||||||
if (node.operator != "=") mark(sym);
|
if (node.operator != "=") mark(sym, true, false);
|
||||||
node.right.walk(tw);
|
node.right.walk(tw);
|
||||||
mark(sym, true);
|
mark(sym, false, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Binary) {
|
if (node instanceof AST_Binary) {
|
||||||
@@ -4357,6 +4357,7 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_For) {
|
if (node instanceof AST_For) {
|
||||||
if (node.init) node.init.walk(tw);
|
if (node.init) node.init.walk(tw);
|
||||||
push();
|
push();
|
||||||
|
segment.block = node;
|
||||||
if (node.condition) node.condition.walk(tw);
|
if (node.condition) node.condition.walk(tw);
|
||||||
node.body.walk(tw);
|
node.body.walk(tw);
|
||||||
if (node.step) node.step.walk(tw);
|
if (node.step) node.step.walk(tw);
|
||||||
@@ -4366,6 +4367,7 @@ merge(Compressor.prototype, {
|
|||||||
if (node instanceof AST_ForIn) {
|
if (node instanceof AST_ForIn) {
|
||||||
node.object.walk(tw);
|
node.object.walk(tw);
|
||||||
push();
|
push();
|
||||||
|
segment.block = node;
|
||||||
node.init.walk(tw);
|
node.init.walk(tw);
|
||||||
node.body.walk(tw);
|
node.body.walk(tw);
|
||||||
pop();
|
pop();
|
||||||
@@ -4385,12 +4387,14 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
if (node instanceof AST_IterationStatement) {
|
if (node instanceof AST_IterationStatement) {
|
||||||
push();
|
push();
|
||||||
|
segment.block = node;
|
||||||
descend();
|
descend();
|
||||||
pop();
|
pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_LabeledStatement) {
|
if (node instanceof AST_LabeledStatement) {
|
||||||
push();
|
push();
|
||||||
|
segment.block = node;
|
||||||
node.body.walk(tw);
|
node.body.walk(tw);
|
||||||
pop();
|
pop();
|
||||||
return true;
|
return true;
|
||||||
@@ -4401,6 +4405,7 @@ merge(Compressor.prototype, {
|
|||||||
if (node.name) references[node.name.definition().id] = false;
|
if (node.name) references[node.name.definition().id] = false;
|
||||||
}
|
}
|
||||||
push();
|
push();
|
||||||
|
segment.block = node;
|
||||||
descend();
|
descend();
|
||||||
pop();
|
pop();
|
||||||
return true;
|
return true;
|
||||||
@@ -4422,11 +4427,11 @@ merge(Compressor.prototype, {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolFunarg) {
|
if (node instanceof AST_SymbolFunarg) {
|
||||||
if (!node.__unused) mark(node, true);
|
if (!node.__unused) mark(node, false, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
mark(node);
|
mark(node, true, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Try) {
|
if (node instanceof AST_Try) {
|
||||||
@@ -4446,13 +4451,13 @@ merge(Compressor.prototype, {
|
|||||||
if (!unary_arithmetic[node.operator]) return;
|
if (!unary_arithmetic[node.operator]) return;
|
||||||
var sym = node.expression;
|
var sym = node.expression;
|
||||||
if (!(sym instanceof AST_SymbolRef)) return;
|
if (!(sym instanceof AST_SymbolRef)) return;
|
||||||
mark(sym);
|
mark(sym, true, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_VarDef) {
|
if (node instanceof AST_VarDef) {
|
||||||
if (node.value) {
|
if (node.value) {
|
||||||
node.value.walk(tw);
|
node.value.walk(tw);
|
||||||
mark(node.name, true);
|
mark(node.name, false, true);
|
||||||
} else {
|
} else {
|
||||||
var id = node.name.definition().id;
|
var id = node.name.definition().id;
|
||||||
if (!(id in references)) {
|
if (!(id in references)) {
|
||||||
@@ -4479,7 +4484,7 @@ merge(Compressor.prototype, {
|
|||||||
if (tail.index > head.index) continue;
|
if (tail.index > head.index) continue;
|
||||||
var id = tail.definition.id;
|
var id = tail.definition.id;
|
||||||
if (!references[id]) continue;
|
if (!references[id]) continue;
|
||||||
if (references[def.id].segment !== references[id].segment) {
|
if (!mergeable()) {
|
||||||
skipped.unshift(tail);
|
skipped.unshift(tail);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -4510,7 +4515,36 @@ merge(Compressor.prototype, {
|
|||||||
segment = Object.getPrototypeOf(segment);
|
segment = Object.getPrototypeOf(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
function read(def) {
|
function mark(sym, read, write) {
|
||||||
|
var def = sym.definition();
|
||||||
|
if (def.id in references) {
|
||||||
|
var refs = references[def.id];
|
||||||
|
if (!refs) return;
|
||||||
|
if (write ? refs.start !== segment : refs.start.block !== segment.block) {
|
||||||
|
return references[def.id] = false;
|
||||||
|
}
|
||||||
|
refs.push(sym);
|
||||||
|
refs.end = segment;
|
||||||
|
if (def.id in prev) {
|
||||||
|
last[prev[def.id]] = null;
|
||||||
|
} else if (!read) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (self.variables.get(def.name) !== def || compressor.exposed(def)) {
|
||||||
|
return references[def.id] = false;
|
||||||
|
} else {
|
||||||
|
var refs = declarations.get(def.id) || [];
|
||||||
|
refs.push(sym);
|
||||||
|
references[def.id] = refs;
|
||||||
|
if (!read) {
|
||||||
|
refs.start = segment;
|
||||||
|
return first.push({
|
||||||
|
index: index++,
|
||||||
|
definition: def,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
refs.start = self;
|
||||||
|
}
|
||||||
prev[def.id] = last.length;
|
prev[def.id] = last.length;
|
||||||
last.push({
|
last.push({
|
||||||
index: index++,
|
index: index++,
|
||||||
@@ -4518,32 +4552,15 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function mark(sym, write_only) {
|
function must_visit(base, segment) {
|
||||||
var def = sym.definition();
|
return base === segment || base.isPrototypeOf(segment);
|
||||||
if (def.id in references) {
|
|
||||||
var refs = references[def.id];
|
|
||||||
if (!refs) return;
|
|
||||||
if (refs.segment !== segment) return references[def.id] = false;
|
|
||||||
refs.push(sym);
|
|
||||||
if (def.id in prev) last[prev[def.id]] = null;
|
|
||||||
read(def);
|
|
||||||
} else if (self.variables.get(def.name) !== def || compressor.exposed(def)) {
|
|
||||||
references[def.id] = false;
|
|
||||||
} else {
|
|
||||||
var refs = declarations.get(def.id) || [];
|
|
||||||
refs.push(sym);
|
|
||||||
references[def.id] = refs;
|
|
||||||
if (write_only) {
|
|
||||||
refs.segment = segment;
|
|
||||||
first.push({
|
|
||||||
index: index++,
|
|
||||||
definition: def,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
refs.segment = self;
|
|
||||||
read(def);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mergeable() {
|
||||||
|
var head = references[def.id];
|
||||||
|
var tail = references[id];
|
||||||
|
if (head.start.block !== tail.start.block) return false;
|
||||||
|
return must_visit(head.start, head.end) || must_visit(head.start, tail.start);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user