diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-01-08 17:15:36 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-01-08 17:15:36 -0800 |
commit | ed106fefa47ea6d156d8ab9cad2dd479e853acbe (patch) | |
tree | 4eee5cffa69db22d1cf1cc84452d1c81be061ead | |
parent | 62ca2bf2fa47370ec845c91bb2c2e73d48d2c4f5 (diff) |
make sure there is a final return in functions that return value in asm
-rw-r--r-- | tools/js-optimizer.js | 12 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-regs-output.js | 13 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-regs.js | 16 |
3 files changed, 40 insertions, 1 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index a8753e6f..446ca723 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1400,6 +1400,7 @@ function registerize(ast, asm) { // We also mark local variables - i.e., having a var definition var localVars = {}; var hasSwitch = false; // we cannot optimize variables if there is a switch + var hasReturnValue = false; traverse(fun, function(node, type) { if (type == 'var') { node[1].forEach(function(defined) { localVars[defined[0]] = 1 }); @@ -1411,6 +1412,8 @@ function registerize(ast, asm) { } } else if (type == 'switch') { hasSwitch = true; + } else if (asm && type == 'return' && node[1]) { + hasReturnValue = true; } }); vacuum(fun); @@ -1587,6 +1590,15 @@ function registerize(ast, asm) { } } denormalizeAsm(fun, finalAsmData); + // Add a final return if one is missing. This is not strictly a register operation, but + // this pass traverses the entire AST anyhow so adding it here is efficient. + if (hasReturnValue) { + var stats = getStatements(fun); + var last = stats[stats.length-1]; + if (last[0] != 'return') { + stats.push(['return', ['num', 0]]); + } + } } }); } diff --git a/tools/test-js-optimizer-asm-regs-output.js b/tools/test-js-optimizer-asm-regs-output.js index d9aa5c0c..26d1d134 100644 --- a/tools/test-js-optimizer-asm-regs-output.js +++ b/tools/test-js-optimizer-asm-regs-output.js @@ -18,4 +18,17 @@ function _doit(i1, i2, i3) { STACKTOP = i1; return 0 | 0; } +function rett() { + if (f()) { + g(); + return 5; + } + return 0; +} +function ret2t() { + if (f()) { + g(); + return; + } +} diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js index 6ae7f7d0..9192f32e 100644 --- a/tools/test-js-optimizer-asm-regs.js +++ b/tools/test-js-optimizer-asm-regs.js @@ -20,5 +20,19 @@ function _doit($x, $y$0, $y$1) { STACKTOP = __stackBase__; return 0 | 0; } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit"] +function rett() { + if (f()) { + g(); + return 5; + } + // missing final return, need to add it +} +function ret2t() { + if (f()) { + g(); + return; + } + // missing final return, but no need +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "rett", "ret2t"] |