diff options
-rw-r--r-- | tests/runner.py | 4 | ||||
-rw-r--r-- | tools/js-optimizer.js | 44 | ||||
-rw-r--r-- | tools/test-js-optimizer-output.js | 4 | ||||
-rw-r--r-- | tools/test-js-optimizer.js | 4 |
4 files changed, 53 insertions, 3 deletions
diff --git a/tests/runner.py b/tests/runner.py index 121f20b5..2eaf65aa 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -4482,7 +4482,7 @@ TT = %s def test_js_optimizer(self): input = open(path_from_root('tools', 'test-js-optimizer.js')).read() expected = open(path_from_root('tools', 'test-js-optimizer-output.js')).read() - output = Popen([NODE_JS, JS_OPTIMIZER, 'unGlobalize', 'removeAssignsToUndefined'], stdin=PIPE, stdout=PIPE).communicate(input)[0] + output = Popen([NODE_JS, JS_OPTIMIZER, 'unGlobalize', 'removeAssignsToUndefined', 'simplifyNotComps'], stdin=PIPE, stdout=PIPE).communicate(input)[0] self.assertIdentical(expected, output.replace('\n\n', '\n')) else: @@ -4520,7 +4520,7 @@ else: #JS_ENGINE = V8_ENGINE Building.COMPILER_TEST_OPTS = [] - POST_OPTIMIZATIONS = ['eliminator', 'closure', ['js-optimizer', 'unGlobalize', 'removeAssignsToUndefined']] + POST_OPTIMIZATIONS = ['eliminator', 'closure', ['js-optimizer', 'unGlobalize', 'removeAssignsToUndefined', 'simplifyNotComps']] TEST_REPS = 10 TOTAL_TESTS = 6 diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index fcf0bbc3..7f613e5f 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -32,6 +32,12 @@ var UNDEFINED_NODE = ['unary-prefix', 'void', ['num', 0]]; var TRUE_NODE = ['unary-prefix', '!', ['num', 0]]; var FALSE_NODE = ['unary-prefix', '!', ['num', 1]]; +var GENERATED_FUNCTIONS_MARKER = '// EMSCRIPTEN_GENERATED_FUNCTIONS:'; +var generatedFunctions = {}; +function isGenerated(ident) { + return ident in generatedFunctions; +} + // Traverses a JavaScript syntax tree rooted at the given node calling the given // callback for each node. // @arg node: The root of the AST. @@ -219,24 +225,60 @@ function removeUnneededLabelSettings(ast) { }); } +// We often have branchings that are simplified so one end vanishes, and +// we then get +// if (!(x < 5)) +// or such. Simplifying these saves space and time. +function simplifyNotComps(ast) { + traverse(ast, function(node, type) { + if (type == 'unary-prefix' && node[1] == '!' && node[2][0] == 'binary') { + if (node[2][1] == '<') { + return ['binary', '>=', node[2][2], node[2][3]]; + } else if (node[2][1] == '>') { + return ['binary', '<=', node[2][2], node[2][3]]; + } else if (node[2][1] == '==') { + return ['binary', '!=', node[2][2], node[2][3]]; + } else if (node[2][1] == '!=') { + return ['binary', '==', node[2][2], node[2][3]]; + } else if (node[2][1] == '===') { + return ['binary', '!==', node[2][2], node[2][3]]; + } else if (node[2][1] == '!==') { + return ['binary', '===', node[2][2], node[2][3]]; + } + } + }); +} + // Passes table var passes = { unGlobalize: unGlobalize, removeAssignsToUndefined: removeAssignsToUndefined, - //removeUnneededLabelSettings: removeUnneededLabelSettings + //removeUnneededLabelSettings: removeUnneededLabelSettings, + simplifyNotComps: simplifyNotComps }; // Main var src = fs.readFileSync('/dev/stdin').toString(); var ast = uglify.parser.parse(src); +//print(JSON.stringify(ast)); var metadata = src.split('\n').filter(function(line) { return line.indexOf('EMSCRIPTEN_GENERATED_FUNCTIONS') >= 0 })[0]; //assert(metadata, 'Must have EMSCRIPTEN_GENERATED_FUNCTIONS metadata'); +//generatedFunctions = set(eval(metadata.replace(GENERATED_FUNCTIONS_MARKER, ''))) arguments.forEach(function(arg) { passes[arg](ast); }); +/* TODO: run only on generated functions (but, some passes look at globals...) +arguments.forEach(function(arg) { + ast[1].forEach(function(node, i) { + if (node[0] == 'defun' && isGenerated(node[1])) { + passes[arg](node); + } + }); +}); +*/ print(uglify.uglify.gen_code(ast, { ascii_only: true, diff --git a/tools/test-js-optimizer-output.js b/tools/test-js-optimizer-output.js index 19b6c87c..73680540 100644 --- a/tools/test-js-optimizer-output.js +++ b/tools/test-js-optimizer-output.js @@ -33,3 +33,7 @@ function xyz2(x) { zzz = (function(nada) { var cheez; }); +function expr() { + if ($0 >= $1) print("hi"); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr"] diff --git a/tools/test-js-optimizer.js b/tools/test-js-optimizer.js index 05e574f9..75679a3a 100644 --- a/tools/test-js-optimizer.js +++ b/tools/test-js-optimizer.js @@ -35,4 +35,8 @@ function xyz2(x) { zzz = function(nada) { var cheez = x; }; +function expr() { + if (!($0 < $1)) print("hi"); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr"] |