was_scope = true;
}
descend(node, this);
- node = node.optimize(this);
- if (was_scope && node instanceof AST_Scope) {
- node.drop_unused(this);
- descend(node, this);
+ descend(node, this);
+ var opt = node.optimize(this);
+ if (was_scope && opt instanceof AST_Scope) {
+ opt.drop_unused(this);
+ descend(opt, this);
}
- node._squeezed = true;
- return node;
+ if (opt === node) opt._squeezed = true;
+ return opt;
}
});
if (compressor.has_directive("use asm")) return self;
var opt = optimizer(self, compressor);
opt._optimized = true;
- if (opt === self) return opt;
- return opt.transform(compressor);
+ return opt;
});
};
if (stat instanceof AST_LoopControl) {
var lct = compressor.loopcontrol_target(stat.label);
if ((stat instanceof AST_Break
- && lct instanceof AST_BlockStatement
+ && !(lct instanceof AST_IterationStatement)
&& loop_body(lct) === self) || (stat instanceof AST_Continue
&& loop_body(lct) === self)) {
if (stat.label) {
return thing && thing.aborts();
};
(function(def){
- def(AST_Statement, function(){ return null });
- def(AST_Jump, function(){ return this });
+ def(AST_Statement, return_null);
+ def(AST_Jump, return_this);
function block_aborts(){
var n = this.body.length;
return n > 0 && aborts(this.body[n - 1]);
// drop_side_effect_free()
// remove side-effect-free parts which only affects return value
(function(def){
- function return_this() {
- return this;
- }
-
- function return_null() {
- return null;
- }
-
// Drop side-effect-free elements from an array of expressions.
// Returns an array of expressions with side-effects or null
// if all elements were dropped. Note: original array may be
extract_declarations_from_unreachable_code(compressor, self.alternative, a);
}
a.push(self.body);
- return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
+ return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
}
} else {
compressor.warn("Condition always false [{file}:{line},{col}]", self.condition.start);
var a = [];
extract_declarations_from_unreachable_code(compressor, self.body, a);
if (self.alternative) a.push(self.alternative);
- return make_node(AST_BlockStatement, self, { body: a }).transform(compressor);
+ return make_node(AST_BlockStatement, self, { body: a }).optimize(compressor);
}
}
}
}
if (is_empty(self.body) && is_empty(self.alternative)) {
return make_node(AST_SimpleStatement, self.condition, {
- body: self.condition
- }).transform(compressor);
+ body: self.condition.clone()
+ }).optimize(compressor);
}
if (self.body instanceof AST_SimpleStatement
&& self.alternative instanceof AST_SimpleStatement) {
consequent : statement_to_expression(self.body),
alternative : statement_to_expression(self.alternative)
})
- }).transform(compressor);
+ }).optimize(compressor);
}
if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) {
if (self_condition_length === negated_length && !negated_is_best
left : negated,
right : statement_to_expression(self.body)
})
- }).transform(compressor);
+ }).optimize(compressor);
return make_node(AST_SimpleStatement, self, {
body: make_node(AST_Binary, self, {
operator : "&&",
left : self.condition,
right : statement_to_expression(self.body)
})
- }).transform(compressor);
+ }).optimize(compressor);
}
if (self.body instanceof AST_EmptyStatement
&& self.alternative
left : self.condition,
right : statement_to_expression(self.alternative)
})
- }).transform(compressor);
+ }).optimize(compressor);
}
if (self.body instanceof AST_Exit
&& self.alternative instanceof AST_Exit
condition : self.condition,
consequent : self.body.value || make_node(AST_Undefined, self.body),
alternative : self.alternative.value || make_node(AST_Undefined, self.alternative)
- })
- }).transform(compressor);
+ }).transform(compressor)
+ }).optimize(compressor);
}
if (self.body instanceof AST_If
&& !self.body.alternative
&& !self.alternative) {
- self.condition = make_node(AST_Binary, self.condition, {
- operator: "&&",
- left: self.condition,
- right: self.body.condition
- }).transform(compressor);
- self.body = self.body.body;
+ self = make_node(AST_If, self, {
+ condition: make_node(AST_Binary, self.condition, {
+ operator: "&&",
+ left: self.condition,
+ right: self.body.condition
+ }),
+ body: self.body.body,
+ alternative: null
+ });
}
if (aborts(self.body)) {
if (self.alternative) {
self.alternative = null;
return make_node(AST_BlockStatement, self, {
body: [ self, alt ]
- }).transform(compressor);
+ }).optimize(compressor);
}
}
if (aborts(self.alternative)) {
self.alternative = null;
return make_node(AST_BlockStatement, self, {
body: [ self, body ]
- }).transform(compressor);
+ }).optimize(compressor);
}
return self;
});