@@ -530,11 +530,16 @@ merge(Compressor.prototype, {
|
||||
tw.safe_ids = save_ids;
|
||||
return true;
|
||||
});
|
||||
def(AST_DWLoop, function(tw, descend) {
|
||||
def(AST_Do, function(tw) {
|
||||
var saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
descend();
|
||||
this.body.walk(tw);
|
||||
if (has_break_or_continue(this)) {
|
||||
pop(tw);
|
||||
push(tw);
|
||||
}
|
||||
this.condition.walk(tw);
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
@@ -543,19 +548,17 @@ merge(Compressor.prototype, {
|
||||
if (this.init) this.init.walk(tw);
|
||||
var saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
if (this.condition) {
|
||||
push(tw);
|
||||
this.condition.walk(tw);
|
||||
pop(tw);
|
||||
}
|
||||
push(tw);
|
||||
if (this.condition) this.condition.walk(tw);
|
||||
this.body.walk(tw);
|
||||
pop(tw);
|
||||
if (this.step) {
|
||||
push(tw);
|
||||
if (has_break_or_continue(this)) {
|
||||
pop(tw);
|
||||
push(tw);
|
||||
}
|
||||
this.step.walk(tw);
|
||||
pop(tw);
|
||||
}
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
});
|
||||
@@ -713,6 +716,15 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
}
|
||||
});
|
||||
def(AST_While, function(tw, descend) {
|
||||
var saved_loop = tw.in_loop;
|
||||
tw.in_loop = this;
|
||||
push(tw);
|
||||
descend();
|
||||
pop(tw);
|
||||
tw.in_loop = saved_loop;
|
||||
return true;
|
||||
});
|
||||
})(function(node, func){
|
||||
node.DEFMETHOD("reduce_vars", func);
|
||||
});
|
||||
@@ -3837,6 +3849,20 @@ merge(Compressor.prototype, {
|
||||
return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
|
||||
});
|
||||
|
||||
function has_break_or_continue(loop, parent) {
|
||||
var found = false;
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (found || node instanceof AST_Scope) return true;
|
||||
if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) {
|
||||
return found = true;
|
||||
}
|
||||
});
|
||||
if (parent instanceof AST_LabeledStatement) tw.push(parent);
|
||||
tw.push(loop);
|
||||
loop.body.walk(tw);
|
||||
return found;
|
||||
}
|
||||
|
||||
OPT(AST_Do, function(self, compressor){
|
||||
if (!compressor.option("loops")) return self;
|
||||
var cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
|
||||
@@ -3851,22 +3877,16 @@ merge(Compressor.prototype, {
|
||||
]
|
||||
})
|
||||
}).optimize(compressor);
|
||||
var has_loop_control = false;
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope || has_loop_control) return true;
|
||||
if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === self)
|
||||
return has_loop_control = true;
|
||||
});
|
||||
var parent = compressor.parent();
|
||||
(parent instanceof AST_LabeledStatement ? parent : self).walk(tw);
|
||||
if (!has_loop_control) return make_node(AST_BlockStatement, self.body, {
|
||||
body: [
|
||||
self.body,
|
||||
make_node(AST_SimpleStatement, self.condition, {
|
||||
body: self.condition
|
||||
})
|
||||
]
|
||||
}).optimize(compressor);
|
||||
if (!has_break_or_continue(self, compressor.parent())) {
|
||||
return make_node(AST_BlockStatement, self.body, {
|
||||
body: [
|
||||
self.body,
|
||||
make_node(AST_SimpleStatement, self.condition, {
|
||||
body: self.condition
|
||||
})
|
||||
]
|
||||
}).optimize(compressor);
|
||||
}
|
||||
}
|
||||
if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, {
|
||||
condition: make_sequence(self.condition, [
|
||||
|
||||
Reference in New Issue
Block a user