From 397bf56d2597d4c2849e380e103b92b87303785f Mon Sep 17 00:00:00 2001 From: Mihai Bazon Date: Sat, 15 Sep 2012 16:06:09 +0300 Subject: [PATCH] other small optimization: if (foo) continue; ...body... ==> if (!foo) { ...body ... } Only when the parent block is the target loop of the `continue` statement. --- lib/compress.js | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 96047291..f8f4d17f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -184,10 +184,44 @@ function Compressor(options, false_by_default) { } while (CHANGED); return statements; + /// XXX: this function is UGLY and kinda wrong. + /// I think it would be cleaner if it operates backwards. function handle_if_return(statements, compressor) { - var in_lambda = compressor.self() instanceof AST_Lambda; + var self = compressor.self(); + var in_lambda = self instanceof AST_Lambda; var last = statements.length - 1; return MAP(statements, function(stat, i){ + if (stat instanceof AST_If + && stat.body instanceof AST_Continue + && !stat.alternative + && self === stat.body.target()) { + CHANGED = true; + if (i < last) { + var rest = statements.slice(i + 1); + var cond = stat.condition; + while (rest[0] instanceof AST_If + && rest[0].body instanceof AST_Continue + && self === rest[0].body.target() + && !rest[0].alternative) { + cond = make_node(AST_Binary, rest[0], { + operator: "||", + left: cond, + right: rest[0].condition + }); + rest.shift(); + } + return MAP.last(make_node(AST_If, stat, { + condition: cond.negate(compressor), + body: make_node(AST_BlockStatement, stat, { + body: rest + }).optimize(compressor) + }).optimize(compressor)) + } else { + return make_node(AST_SimpleStatement, stat, { + body: stat.condition + }).optimize(compressor); + } + } if (stat instanceof AST_If && stat.body instanceof AST_Return && !stat.alternative @@ -199,6 +233,7 @@ function Compressor(options, false_by_default) { var cond = stat.condition; while (rest[0] instanceof AST_If && rest[0].body instanceof AST_Return + && !rest[0].body.value && !rest[0].alternative) { cond = make_node(AST_Binary, rest[0], { operator: "||", @@ -645,7 +680,10 @@ function Compressor(options, false_by_default) { (function(def){ def(AST_StatementBase, function(){ return null }); def(AST_Jump, function(){ return this }); - def(AST_BlockStatement, function(){ return this.body[this.body.length - 1].aborts() }); + def(AST_BlockStatement, function(){ + var n = this.body.length; + return n > 0 && this.body[n - 1].aborts(); + }); })(function(node, func){ node.DEFMETHOD("aborts", func); }); -- 2.34.1