AST_Scope.DEFMETHOD("merge_variables", function(compressor) {
if (!compressor.option("merge_vars")) return;
- var self = this, segment = self;
+ var self = this, segment;
var first = [], last = [], index = 0;
var references = Object.create(null);
var prev = Object.create(null);
if (node instanceof AST_Conditional) {
node.condition.walk(tw);
var save = segment;
- segment = node;
+ segment = node.consequent;
node.consequent.walk(tw);
+ segment = node.alternative;
node.alternative.walk(tw);
segment = save;
return true;
var save = segment;
segment = node;
node.body.walk(tw);
- if (node.alternative) node.alternative.walk(tw);
+ if (node.alternative) {
+ segment = node.alternative;
+ node.alternative.walk(tw);
+ }
segment = save;
return true;
}
}
if (node instanceof AST_Switch) {
node.expression.walk(tw);
- var save = segment;
- segment = node;
+ var save = segment, first = true;
node.body.forEach(function(branch) {
- branch.walk(tw);
+ if (branch instanceof AST_Default) return;
+ if (first) {
+ first = false;
+ } else {
+ segment = branch.expression;
+ }
+ branch.expression.walk(tw);
+ });
+ node.body.forEach(function(branch) {
+ segment = branch;
+ branch.body.forEach(function(stat) {
+ stat.walk(tw);
+ });
});
segment = save;
return true;
node.body.forEach(function(branch) {
branch.walk(tw);
});
- if (node.bcatch) node.bcatch.walk(tw);
+ if (node.bcatch) {
+ segment = node.bcatch;
+ node.bcatch.walk(tw);
+ }
segment = save;
if (node.bfinally) node.bfinally.walk(tw);
return true;
if (!(def.id in prev)) continue;
if (!references[def.id]) continue;
while (def.id in merged) def = merged[def.id];
+ var skipped = [];
do {
var tail = last.pop();
if (!tail) continue;
if (tail.index > head.index) continue;
if (!references[tail.definition.id]) continue;
+ if (references[def.id].segment !== references[tail.definition.id].segment) {
+ skipped.unshift(tail);
+ continue;
+ }
var orig = [], refs = [];
references[tail.definition.id].forEach(function(sym) {
push(sym);
merged[tail.definition.id] = def;
break;
} while (last.length);
+ if (skipped.length) last = last.concat(skipped);
}
function read(def) {
function mark(sym, write_only) {
var def = sym.definition();
- if (segment !== self) references[def.id] = false;
if (def.id in references) {
- if (!references[def.id]) return;
- references[def.id].push(sym);
+ 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 (compressor.exposed(def) || self.variables.get(def.name) !== def) {
+ } else if (self.variables.get(def.name) !== def || compressor.exposed(def)) {
references[def.id] = false;
} else {
- references[def.id] = [ sym ];
- if (!write_only) return read(def);
- first.push({
- index: index++,
- definition: def,
- });
+ var refs = [ sym ];
+ references[def.id] = refs;
+ if (write_only) {
+ refs.segment = segment;
+ first.push({
+ index: index++,
+ definition: def,
+ });
+ } else {
+ refs.segment = self;
+ read(def);
+ }
}
}