aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Kelly <ryan@rfk.id.au>2014-01-28 18:59:50 +1100
committerRyan Kelly <ryan@rfk.id.au>2014-01-31 19:12:10 +1100
commitb175281cb1d1e1a27339bddedfa6ff4fc0822fca (patch)
tree16f2a05def27eaacf9ddbd8817415fcf837d7d00
parent26900e3bd6946ce74b947e4479b35b683b819ff2 (diff)
Teach buildFlowGraph about functions that are known to always throw.
It can treat calls to these functions like a jump to function exit, allowing for more accurate tracking of dead junctions.
-rw-r--r--tests/test_core.py2
-rw-r--r--tools/js-optimizer.js9
2 files changed, 9 insertions, 2 deletions
diff --git a/tests/test_core.py b/tests/test_core.py
index d0de0031..bbc6370a 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1158,8 +1158,6 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
def test_longjmp_throw(self):
- if self.run_name == 'asm3': return self.skip('issue 2069') # FIXME
-
for disable_throw in [0, 1]:
print disable_throw
Settings.DISABLE_EXCEPTION_CATCHING = disable_throw
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index adffc184..d12f4f4d 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -140,6 +140,8 @@ var ALTER_FLOW = set('break', 'continue', 'return');
var BREAK_CAPTURERS = set('do', 'while', 'for', 'switch');
var CONTINUE_CAPTURERS = LOOP;
+var FUNCTIONS_THAT_ALWAYS_THROW = set('abort', '___resumeException', '___cxa_throw', '___cxa_rethrow');
+
var NULL_NODE = ['name', 'null'];
var UNDEFINED_NODE = ['unary-prefix', 'void', ['num', 0]];
var TRUE_NODE = ['unary-prefix', '!', ['num', 0]];
@@ -2579,6 +2581,13 @@ function registerizeHarder(ast) {
}
}
isInExpr--;
+ // If the call is statically known to throw,
+ // treat it as a jump to function exit.
+ if (!isInExpr && node[1][0] === 'name') {
+ if (node[1][1] in FUNCTIONS_THAT_ALWAYS_THROW) {
+ markNonLocalJump('return');
+ }
+ }
break;
case 'seq':
case 'sub':