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;
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;
});
}
}
});
+ 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);
});
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);
]
})
}).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, [