aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js95
1 files changed, 55 insertions, 40 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 206c77f3..e6215f66 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -3020,34 +3020,40 @@ merge(Compressor.prototype, {
return self;
});
- OPT(AST_DWLoop, function(self, compressor){
+ OPT(AST_While, function(self, compressor){
+ return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
+ });
+
+ OPT(AST_Do, function(self, compressor){
if (!compressor.option("loops")) return self;
- var cond = self.condition.evaluate(compressor);
- if (cond !== self.condition) {
- if (cond) {
- return make_node(AST_For, self, {
- body: self.body
- });
- }
- if (compressor.option("dead_code") && self instanceof AST_While) {
- var a = [];
- extract_declarations_from_unreachable_code(compressor, self.body, a);
- return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
- }
- if (self instanceof AST_Do) {
- 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 self.body;
- }
- }
- if (self instanceof AST_While) {
- return make_node(AST_For, self, self).optimize(compressor);
+ var cond = self.condition.tail_node().evaluate(compressor);
+ if (!(cond instanceof AST_Node)) {
+ if (cond) return make_node(AST_For, self, {
+ body: make_node(AST_BlockStatement, self.body, {
+ body: [
+ self.body,
+ make_node(AST_SimpleStatement, self.condition, {
+ body: self.condition
+ })
+ ]
+ })
+ }).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);
}
return self;
});
@@ -3101,22 +3107,31 @@ merge(Compressor.prototype, {
if (!compressor.option("loops")) return self;
if (self.condition) {
var cond = self.condition.evaluate(compressor);
- if (compressor.option("dead_code") && !cond) {
- var a = [];
- if (self.init instanceof AST_Statement) {
- a.push(self.init);
+ if (!(cond instanceof AST_Node)) {
+ if (cond) self.condition = null;
+ else if (!compressor.option("dead_code")) {
+ var orig = self.condition;
+ self.condition = make_node_from_constant(cond, self.condition);
+ self.condition = best_of_expression(self.condition.transform(compressor), orig);
}
- else if (self.init) {
- a.push(make_node(AST_SimpleStatement, self.init, {
- body: self.init
+ }
+ if (compressor.option("dead_code")) {
+ if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor);
+ if (!cond) {
+ var body = [];
+ extract_declarations_from_unreachable_code(compressor, self.body, body);
+ body.push(make_node(AST_SimpleStatement, self.condition, {
+ body: self.condition
}));
+ if (self.init instanceof AST_Statement) {
+ body.push(self.init);
+ } else if (self.init) {
+ body.push(make_node(AST_SimpleStatement, self.init, {
+ body: self.init
+ }));
+ }
+ return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor);
}
- extract_declarations_from_unreachable_code(compressor, self.body, a);
- return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
- }
- if (cond !== self.condition) {
- cond = make_node_from_constant(cond, self.condition).transform(compressor);
- self.condition = best_of_expression(cond, self.condition);
}
}
if_break_in_loop(self, compressor);