Migrate language_2/exception to NNBD.

Change-Id: I0f758fce0af79be77b2fc885afcc3bd17d9fb55e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142701
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Leaf Petersen <leafp@google.com>
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/tests/language/exception/catch_liveness_test.dart b/tests/language/exception/catch_liveness_test.dart
new file mode 100644
index 0000000..df9a3dd
--- /dev/null
+++ b/tests/language/exception/catch_liveness_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+foo() => 1;
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+throwException() => throw 'x';
+
+main() {
+  var x = 10;
+  var e2 = null;
+  try {
+    var t = foo();
+    throwException();
+    print(t);
+    x = 3;
+  } catch (e) {
+    Expect.equals(10, x);
+    e2 = e;
+  }
+  Expect.equals(10, x);
+  Expect.equals('x', e2);
+}
diff --git a/tests/language/exception/code_after_try_is_executed_test.dart b/tests/language/exception/code_after_try_is_executed_test.dart
new file mode 100644
index 0000000..57ffd84
--- /dev/null
+++ b/tests/language/exception/code_after_try_is_executed_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test that the runtime still runs the code after a try/catch. The
+// test cannot use Expect.throws, because Expect.throws uses the same
+// pattern.
+
+import "package:expect/expect.dart";
+
+main() {
+  var exception;
+  try {
+    throw 'foo';
+  } on String catch (ex) {
+    exception = ex;
+  }
+  Expect.isTrue(exception is String);
+  throw 'foo'; //# 01: runtime error
+}
diff --git a/tests/language/exception/exception_test.dart b/tests/language/exception/exception_test.dart
new file mode 100644
index 0000000..86c2206
--- /dev/null
+++ b/tests/language/exception/exception_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class ExceptionTest {
+  static testMain() {
+    int i = 0;
+    try {
+      throw "Hello";
+    } on String catch (s) {
+      print(s);
+      i += 10;
+    }
+
+    try {
+      throw "bye";
+    } on String catch (s) {
+      print(s);
+      i += 10;
+    }
+    Expect.equals(20, i);
+
+    bool correctCatch = false;
+    try {
+      // This throws NullThrownError
+      throw (null as dynamic);
+    } on String catch (s) {
+      correctCatch = false;
+    } on NullThrownError catch (e) {
+      correctCatch = true;
+    } catch (x) {
+      correctCatch = false;
+    }
+    Expect.isTrue(correctCatch);
+  }
+}
+
+main() {
+  ExceptionTest.testMain();
+}
diff --git a/tests/language/exception/finally10_test.dart b/tests/language/exception/finally10_test.dart
new file mode 100644
index 0000000..dfe47b5
--- /dev/null
+++ b/tests/language/exception/finally10_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a catch block that throws.
+
+import "package:expect/expect.dart";
+
+class A {
+  var field;
+  start() {}
+  stop() {
+    field = 42;
+  }
+}
+
+class B {
+  var totalCompileTime = new A();
+  var runCompiler = new Object();
+
+  run() {
+    totalCompileTime.start();
+    try {
+      throw 'foo';
+    } catch (exception) {
+      // Use [runCompiler] twice to ensure it will have a local
+      // variable.
+      runCompiler.toString();
+      runCompiler.toString();
+      rethrow;
+    } finally {
+      totalCompileTime.stop();
+    }
+  }
+}
+
+main() {
+  var b = new B();
+  try {
+    b.run();
+    throw 'Expected exception';
+  } catch (exception) {
+    // Expected exception.
+  }
+
+  Expect.equals(42, b.totalCompileTime.field);
+}
diff --git a/tests/language/exception/finally11_test.dart b/tests/language/exception/finally11_test.dart
new file mode 100644
index 0000000..dbe7288
--- /dev/null
+++ b/tests/language/exception/finally11_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a nested try block.
+
+import "package:expect/expect.dart";
+
+class A {
+  var field;
+  start() {}
+  stop() {
+    field = 42;
+  }
+}
+
+class B {
+  var totalCompileTime = new A();
+  var runCompiler = new Object();
+
+  run() {
+    totalCompileTime.start();
+    try {
+      throw 'foo';
+    } catch (exception) {
+      try {
+        // Use [runCompiler] twice to ensure it will have a local
+        // variable.
+        runCompiler.toString();
+        runCompiler.toString();
+      } catch (exception) {}
+      rethrow;
+    } finally {
+      totalCompileTime.stop();
+    }
+  }
+}
+
+main() {
+  var b = new B();
+  try {
+    b.run();
+    throw 'Expected exception';
+  } catch (exception) {
+    // Expected exception.
+  }
+
+  Expect.equals(42, b.totalCompileTime.field);
+}
diff --git a/tests/language/exception/finally12_test.dart b/tests/language/exception/finally12_test.dart
new file mode 100644
index 0000000..e4f56a0
--- /dev/null
+++ b/tests/language/exception/finally12_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to not treat the finally
+// block as a successor of a nested try block.
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo() {
+  var b = a == 8; // This should not be GVN'ed.
+  while (!b) {
+    try {
+      try {} finally {
+        a = 8;
+        break;
+      }
+    } finally {
+      return a == 8;
+    }
+  }
+}
+
+main() {
+  Expect.isTrue(foo());
+}
diff --git a/tests/language/exception/finally1_test.dart b/tests/language/exception/finally1_test.dart
new file mode 100644
index 0000000..0e8510a
--- /dev/null
+++ b/tests/language/exception/finally1_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      int j;
+      j = func();
+      i = 1;
+      return i; // Value of i on return is 1.
+    } finally {
+      i = i + 800; // Should get executed on return.
+    }
+    return i + 200; // Should not get executed.
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally1Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.f1());
+    Expect.equals(801, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally1Test.testMain();
+}
diff --git a/tests/language/exception/finally2_test.dart b/tests/language/exception/finally2_test.dart
new file mode 100644
index 0000000..fd64f69
--- /dev/null
+++ b/tests/language/exception/finally2_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      int j;
+      j = func();
+      try {
+        i = 1;
+        return i; // Value of i is 1 on return.
+      } finally {
+        i = i + 400; // Should get executed when we return.
+      }
+      i = 2; // Should not get executed.
+      return i;
+    } finally {
+      i = i + 800; // Should get executed when we return.
+    }
+    return i + 200; // Should not get executed.
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally2Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.f1());
+    Expect.equals(1201, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally2Test.testMain();
+}
diff --git a/tests/language/exception/finally3_test.dart b/tests/language/exception/finally3_test.dart
new file mode 100644
index 0000000..c36ba0f
--- /dev/null
+++ b/tests/language/exception/finally3_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      try {
+        int j;
+        j = func();
+        L1:
+        while (i <= 0) {
+          if (i == 0) {
+            try {
+              i = 1;
+              func();
+              try {
+                int j;
+                j = func();
+                while (j < 50) {
+                  j += func();
+                  if (j > 30) {
+                    continue L1; // Break out of nested try blocks.
+                  }
+                }
+                i = 200000; // Should not get executed.
+              } finally {
+                i = i + 200; // Should get executed when we break out.
+              }
+            } finally {
+              i = i + 400; // Should get executed when we break out.
+            }
+          }
+        }
+      } finally {
+        i = i + 800; // Should get executed as normal control flow.
+      }
+      return i; // Value of i should be 1401.
+    } finally {
+      i = i + 1600; // Should get executed as part of return above.
+    }
+    i = i + 2000000; // Should not get executed.
+    return 1;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally3Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1401, obj.f1());
+    Expect.equals(3001, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally3Test.testMain();
+}
diff --git a/tests/language/exception/finally4_test.dart b/tests/language/exception/finally4_test.dart
new file mode 100644
index 0000000..fcc308c
--- /dev/null
+++ b/tests/language/exception/finally4_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      int j;
+      j = func();
+      i = 1;
+    } finally {
+      i = i + 10;
+    }
+    return i + 200; // Should return here with i = 211.
+    try {
+      int j;
+      j = func();
+    } finally {
+      i = i + 10; // Should not get executed as part of return above.
+    }
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally4Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(211, obj.f1());
+    Expect.equals(11, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally4Test.testMain();
+}
diff --git a/tests/language/exception/finally5_test.dart b/tests/language/exception/finally5_test.dart
new file mode 100644
index 0000000..09cbdc15
--- /dev/null
+++ b/tests/language/exception/finally5_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1(int param) {
+    if (param == 0) {
+      try {
+        int j;
+        j = func();
+        try {
+          i = 1;
+          return i; // Value of i is 1 on return.
+        } finally {
+          i = i + 400; // Should get executed when we return.
+        }
+        i = 2; // Should not get executed.
+        return i;
+      } finally {
+        i = i + 800; // Should get executed when we return.
+      }
+      return i + 200; // Should not get executed.
+    }
+    try {
+      int j;
+      j = func();
+      try {
+        i = 4;
+        return i; // Value of i is 1 on return.
+      } finally {
+        i = i + 100; // Should get executed when we return.
+      }
+      i = 2; // Should not get executed.
+      return i;
+    } finally {
+      i = i + 200; // Should get executed when we return.
+    }
+    return i + 200; // Should not get executed.
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally5Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(1, obj.f1(0));
+    Expect.equals(1201, obj.i);
+    Expect.equals(4, obj.f1(1));
+    Expect.equals(304, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally5Test.testMain();
+}
diff --git a/tests/language/exception/finally6_test.dart b/tests/language/exception/finally6_test.dart
new file mode 100644
index 0000000..e9c5ea5
--- /dev/null
+++ b/tests/language/exception/finally6_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks on
+// control flow breaks because of 'return', 'continue' etc.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    try {
+      try {
+        int j;
+        j = func();
+        L1:
+        while (i <= 0) {
+          if (i == 0) {
+            try {
+              i = 1;
+              func();
+              try {
+                int j;
+                j = func();
+                L1:
+                while (j < 50) {
+                  j += func();
+                  if (j > 30) {
+                    break L1; // Break out of nested try blocks.
+                  }
+                }
+                i += 200000; // Should get executed.
+              } finally {
+                i = i + 200; // Should get executed as normal control flow.
+              }
+            } finally {
+              i = i + 400; // Should get executed as normal control flow.
+            }
+          }
+        }
+      } finally {
+        i = i + 800; // Should get executed as normal control flow.
+      }
+      return i; // Value of i should be 201401.
+    } finally {
+      i = i + 1600; // Should get executed as part of return above.
+    }
+    i = i + 2000000; // Should not get executed.
+    return 1;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class ExecuteFinally6Test {
+  static testMain() {
+    Helper obj = new Helper();
+    Expect.equals(201401, obj.f1());
+    Expect.equals(203001, obj.i);
+  }
+}
+
+main() {
+  ExecuteFinally6Test.testMain();
+}
diff --git a/tests/language/exception/finally7_test.dart b/tests/language/exception/finally7_test.dart
new file mode 100644
index 0000000..afa6a67
--- /dev/null
+++ b/tests/language/exception/finally7_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing execution of finally blocks after an exception
+// is thrown from inside a local function capturing a variable.
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException(String message) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  static int f1(int k) {
+    var b;
+    try {
+      var a = new List<dynamic>.filled(10, null);
+      int i = 0;
+      while (i < 10) {
+        int j = i;
+        a[i] = () {
+          if (j == 5) {
+            throw new MyException("Test for exception being thrown");
+          }
+          k += 10;
+          return j;
+        };
+        if (i == 0) {
+          b = a[i];
+        }
+        i++;
+      }
+      for (int i = 0; i < 10; i++) {
+        a[i]();
+      }
+    } on MyException catch (exception) {
+      k += 100;
+      print(exception.message_);
+      b();
+    } finally {
+      k += 1000;
+      b();
+    }
+    return k;
+  }
+}
+
+class ExecuteFinally7Test {
+  static testMain() {
+    Expect.equals(1171, Helper.f1(1));
+  }
+}
+
+main() {
+  ExecuteFinally7Test.testMain();
+}
diff --git a/tests/language/exception/finally8_test.dart b/tests/language/exception/finally8_test.dart
new file mode 100644
index 0000000..c697eee
--- /dev/null
+++ b/tests/language/exception/finally8_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// This test ensures that the finally block executes correctly when
+// there are throw, break and return statements in the finally block.
+
+import "package:expect/expect.dart";
+
+class Hello {
+  static var sum;
+
+  static foo() {
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } finally {
+      sum += 1;
+      throw 'ball';
+      sum += 1;
+    }
+  }
+
+  static foo1() {
+    bool loop = true;
+    sum = 0;
+    L:
+    while (loop) {
+      try {
+        sum += 1;
+        return 'hi';
+      } finally {
+        sum += 1;
+        break L;
+        sum += 1;
+      }
+    }
+  }
+
+  static foo2() {
+    bool loop = true;
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } finally {
+      sum += 1;
+      return 10;
+      sum += 1;
+    }
+  }
+
+  static foo3() {
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } finally {
+      sum += 1;
+      return 10;
+      sum += 1;
+    }
+  }
+
+  static void main() {
+    foo1();
+    Expect.equals(2, sum);
+    foo2();
+    Expect.equals(2, sum);
+    foo3();
+    Expect.equals(2, sum);
+    try {
+      foo();
+    } catch (e) {}
+    Expect.equals(2, sum);
+  }
+}
+
+main() {
+  Hello.main();
+}
diff --git a/tests/language/exception/finally9_test.dart b/tests/language/exception/finally9_test.dart
new file mode 100644
index 0000000..5513466
--- /dev/null
+++ b/tests/language/exception/finally9_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// This test ensures that the finally block executes correctly when
+// there are throw, break and return statements in the finally block.
+
+import "package:expect/expect.dart";
+
+class Hello {
+  static var sum;
+
+  static foo() {
+    sum = 0;
+    try {
+      sum += 1;
+      return 'hi';
+    } catch (e) {
+      sum += 1;
+      throw 'ball';
+      sum += 1;
+    } finally {
+      sum += 1;
+      throw 'ball';
+      sum += 1;
+    }
+  }
+
+  static foo1() {
+    bool loop = true;
+    sum = 0;
+    L:
+    while (loop) {
+      try {
+        sum += 1;
+        return 'hi';
+      } catch (ex) {
+        sum += 1;
+      } finally {
+        try {
+          L1:
+          while (loop) {
+            sum += 1;
+            break L;
+            sum += 1;
+          }
+        } catch (ex) {
+          sum += 1;
+        } finally {
+          sum += 1;
+        }
+      }
+    }
+  }
+
+  static void main() {
+    foo1();
+    Expect.equals(3, sum);
+    try {
+      foo();
+    } catch (e) {
+      // Ignore.
+    }
+    Expect.equals(2, sum);
+  }
+}
+
+main() {
+  Hello.main();
+}
diff --git a/tests/language/exception/finally_test.dart b/tests/language/exception/finally_test.dart
new file mode 100644
index 0000000..9277416
--- /dev/null
+++ b/tests/language/exception/finally_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test for a bug in dart2js where the update of a field in a try
+// block would not be seen by the finally block. See dartbug.com/5517.
+
+class A {
+  int i;
+  A() : i = 42;
+
+  foo() {
+    bool executedFinally = false;
+    if (i == 42) {
+      try {
+        i = 12;
+      } finally {
+        Expect.equals(12, i);
+        executedFinally = true;
+      }
+    }
+    Expect.isTrue(executedFinally);
+  }
+}
+
+main() {
+  new A().foo();
+}
diff --git a/tests/language/exception/identity_test.dart b/tests/language/exception/identity_test.dart
new file mode 100644
index 0000000..2b16607
--- /dev/null
+++ b/tests/language/exception/identity_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that an object when thrown stays the same.
+
+class A {
+  A();
+}
+
+check(exception) {
+  try {
+    throw exception;
+  } catch (e) {
+    Expect.equals(exception, e);
+  }
+}
+
+main() {
+  check("str");
+  check(new A());
+  check(1);
+  check(1.2);
+}
diff --git a/tests/language/exception/in_increment_test.dart b/tests/language/exception/in_increment_test.dart
new file mode 100644
index 0000000..5e34a60
--- /dev/null
+++ b/tests/language/exception/in_increment_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test throws exception in the middle of the increment operation, the setter
+// part of the instance field increment never completes.
+// VMOptions=--optimization-counter-threshold=10
+
+main() {
+  var a = new A();
+  a.field = new A();
+  for (int i = 0; i < 20; i++) {
+    try {
+      a.foo(i);
+    } catch (e) {
+      // Ignore.
+    }
+  }
+}
+
+class A {
+  var field;
+  foo(i) {
+    field++; // throw exception
+  }
+}
diff --git a/tests/language/exception/on_catch_malformed_type_test.dart b/tests/language/exception/on_catch_malformed_type_test.dart
new file mode 100644
index 0000000..8b49027
--- /dev/null
+++ b/tests/language/exception/on_catch_malformed_type_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that malformed types in on-catch are handled correctly, that is,
+// throws a type error in both production and checked mode.
+
+import 'package:expect/expect.dart';
+
+catchUnresolvedBefore() {
+  try {
+    throw "foo";
+    Expect.fail("This code shouldn't be executed");
+  } on String catch (oks) {
+    // This is tested before the catch block below.
+  } on Unavailable catch (ex) { /*@compile-error=unspecified*/
+    Expect.fail("This code shouldn't be executed");
+  }
+}
+
+catchUnresolvedAfter() {
+  Expect.throwsTypeError(() {
+    try {
+      throw "foo";
+      Expect.fail("This code shouldn't be executed");
+    } on Unavailable catch (ex) { /*@compile-error=unspecified*/
+      // This is tested before the catch block below.
+      // In both production and checked mode the test causes a type error.
+    } on String catch (oks) {
+      Expect.fail("This code shouldn't be executed");
+    }
+  });
+}
+
+main() {
+  catchUnresolvedBefore();
+  catchUnresolvedAfter();
+}
diff --git a/tests/language/exception/rethrow_test.dart b/tests/language/exception/rethrow_test.dart
new file mode 100644
index 0000000..0b0d3bc
--- /dev/null
+++ b/tests/language/exception/rethrow_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException();
+}
+
+class OtherException {
+  const OtherException();
+}
+
+class RethrowTest {
+  late MyException currentException;
+
+  void throwException() {
+    currentException = new MyException();
+    throw currentException;
+  }
+
+  void testRethrowPastUncaught() {
+    try {
+      try {
+        try {
+          throwException();
+          Expect.fail("Should have thrown an exception");
+        } catch (e) {
+          Expect.equals(true, identical(e, currentException));
+          rethrow;
+          Expect.fail("Should have thrown an exception");
+        }
+      } on OtherException catch (e) {
+        Expect.fail("Should not have caught OtherException");
+      }
+    } catch (e) {
+      Expect.equals(true, identical(e, currentException));
+    }
+  }
+
+  void testRethrow() {
+    try {
+      try {
+        throwException();
+        Expect.fail("Should have thrown an exception");
+      } catch (e) {
+        Expect.equals(true, identical(e, currentException));
+        rethrow;
+        Expect.fail("Should have thrown an exception");
+      }
+    } catch (e) {
+      Expect.equals(true, identical(e, currentException));
+    }
+  }
+}
+
+main() {
+  RethrowTest t = new RethrowTest();
+  t.testRethrow();
+  t.testRethrowPastUncaught();
+}
diff --git a/tests/language/exception/throw1_test.dart b/tests/language/exception/throw1_test.dart
new file mode 100644
index 0000000..1ae121e
--- /dev/null
+++ b/tests/language/exception/throw1_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException2 implements TestException {
+  const MyException2([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException3 implements TestException {
+  const MyException3([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+      if (j > 0) {
+        throw new MyException2("Test for exception being thrown");
+      }
+    } on MyException3 catch (exception) {
+      i = 100;
+      print(exception.getMessage());
+    } on TestException catch (exception) {
+      i = 50;
+      print(exception.getMessage());
+    } on MyException2 catch (exception) {
+      i = 150;
+      print(exception.getMessage());
+    } on MyException catch (exception) {
+      i = 200;
+      print(exception.getMessage());
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class Throw1Test {
+  static testMain() {
+    Expect.equals(850, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw1Test.testMain();
+}
diff --git a/tests/language/exception/throw2_test.dart b/tests/language/exception/throw2_test.dart
new file mode 100644
index 0000000..eaade24
--- /dev/null
+++ b/tests/language/exception/throw2_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException2 implements TestException {
+  const MyException2([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class MyException3 implements TestException {
+  const MyException3([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+    } on MyException3 catch (exception) {
+      i = 100;
+      print(exception.getMessage());
+    } on MyException2 catch (exception) {
+      try {
+        i = func2();
+        i = 200;
+      } on TestException catch (exception) {
+        i = 50;
+      }
+      print(exception.getMessage());
+    } on MyException catch (exception) {
+      i = func2();
+      print(exception.getMessage());
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    if (i > 0) {
+      throw new MyException2("Test for exception being thrown");
+    }
+    return i;
+  }
+
+  static int func2() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    if (i > 0) {
+      throw new MyException2("Test for exception being thrown");
+    }
+    return i;
+  }
+}
+
+class Throw2Test {
+  static testMain() {
+    Expect.equals(850, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw2Test.testMain();
+}
diff --git a/tests/language/exception/throw3_test.dart b/tests/language/exception/throw3_test.dart
new file mode 100644
index 0000000..1d72345
--- /dev/null
+++ b/tests/language/exception/throw3_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException([String message = ""]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      i = 100;
+      i = func();
+      i = 200;
+    } on MyException catch (exception) {
+      i = 50;
+      print(exception.message_);
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    try {
+      int i = 0;
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException("Test for exception being thrown");
+      }
+    } on MyException catch (ex) {
+      print(ex.message_);
+      rethrow; // Rethrow the exception.
+    }
+    return 10;
+  }
+}
+
+class Throw3Test {
+  static testMain() {
+    Expect.equals(850, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw3Test.testMain();
+}
diff --git a/tests/language/exception/throw4_test.dart b/tests/language/exception/throw4_test.dart
new file mode 100644
index 0000000..6dd2f74
--- /dev/null
+++ b/tests/language/exception/throw4_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+  const MyException1([String message = "1"]) : message_ = message;
+  final String message_;
+}
+
+class MyException2 {
+  const MyException2([String message = "2"]) : message_ = message;
+  final String message_;
+}
+
+class MyException3 {
+  const MyException3([String message = "3"]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    int j = 0;
+    try {
+      j = func();
+    } on MyException3 catch (exception) {
+      i = i + 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = i + 200;
+      print(exception.message_);
+    } on MyException1 catch (exception) {
+      i = i + 100;
+      print(exception.message_);
+    } finally {
+      i = i + 1000;
+    }
+    return i;
+  }
+
+  // No catch in the same function for the type of exception being thrown
+  // in the try block here. We expect the handler if checks to fall thru,
+  // the finally block to run and an implicit rethrow to happen.
+  int func() {
+    i = 0;
+    try {
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException1("Test for MyException1 being thrown");
+      }
+    } on MyException3 catch (exception) {
+      i = 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = 200;
+      print(exception.message_);
+    } finally {
+      i = 800;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class Throw4Test {
+  static testMain() {
+    Expect.equals(1900, new Helper().f1());
+  }
+}
+
+main() {
+  Throw4Test.testMain();
+}
diff --git a/tests/language/exception/throw5_test.dart b/tests/language/exception/throw5_test.dart
new file mode 100644
index 0000000..349ade7
--- /dev/null
+++ b/tests/language/exception/throw5_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+  const MyException1([String message = "1"]) : message_ = message;
+  final String message_;
+}
+
+class MyException2 {
+  const MyException2([String message = "2"]) : message_ = message;
+  final String message_;
+}
+
+class MyException3 {
+  const MyException3([String message = "3"]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+    } on MyException3 catch (exception) {
+      i = 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = 200;
+      print(exception.message_);
+    } on MyException1 catch (exception) {
+      i = 100;
+      print(exception.message_);
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  // No catch in the same function for the type of exception being thrown
+  // in the try block here. We expect the handler if checks to fall thru and
+  // implicit rethrow to happen.
+  static int func() {
+    int i = 0;
+    try {
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException1("Test for MyException1 being thrown");
+      }
+    } on MyException3 catch (exception) {
+      i = 300;
+      print(exception.message_);
+    } on MyException2 catch (exception) {
+      i = 200;
+      print(exception.message_);
+    }
+    return i;
+  }
+}
+
+class Throw5Test {
+  static testMain() {
+    Expect.equals(900, Helper.f1(1));
+  }
+}
+
+main() {
+  Throw5Test.testMain();
+}
diff --git a/tests/language/exception/throw6_test.dart b/tests/language/exception/throw6_test.dart
new file mode 100644
index 0000000..1433467
--- /dev/null
+++ b/tests/language/exception/throw6_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException1 {
+  const MyException1([String message = "1"]) : message_ = message;
+  final String message_;
+}
+
+class Helper {
+  Helper() : i = 0 {}
+
+  int f1() {
+    int j = 0;
+    try {
+      j = func();
+    } catch (exception) {
+      i = i + 100;
+      print(exception.message_);
+    } finally {
+      i = i + 1000;
+    }
+    return i;
+  }
+
+  // No catch in the same function for the type of exception being thrown
+  // in the try block here. We expect the handler if checks to fall thru,
+  // the finally block to run and an implicit rethrow to happen.
+  int func() {
+    i = 0;
+    try {
+      while (i < 10) {
+        i++;
+      }
+      if (i > 0) {
+        throw new MyException1("Test for MyException1 being thrown");
+      }
+    } finally {
+      i = 800;
+    }
+    return i;
+  }
+
+  int i;
+}
+
+class Throw6Test {
+  static testMain() {
+    Expect.equals(1900, new Helper().f1());
+  }
+}
+
+main() {
+  Throw6Test.testMain();
+}
diff --git a/tests/language/exception/throw8_test.dart b/tests/language/exception/throw8_test.dart
new file mode 100644
index 0000000..de84012
--- /dev/null
+++ b/tests/language/exception/throw8_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+var finallyExecutionCount = 0;
+bar() {
+  try {
+    try {
+      return 499;
+    } catch (e, st) {
+      rethrow;
+    }
+  } finally {
+    finallyExecutionCount++;
+    throw "quit finally with throw";
+  }
+}
+
+main() {
+  bool hasThrown = false;
+  try {
+    bar();
+  } catch (x) {
+    hasThrown = true;
+    Expect.equals(1, finallyExecutionCount);
+  }
+  Expect.isTrue(hasThrown);
+}
diff --git a/tests/language/exception/throw_expr_test.dart b/tests/language/exception/throw_expr_test.dart
new file mode 100644
index 0000000..c1f5044
--- /dev/null
+++ b/tests/language/exception/throw_expr_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test program for testing throw expressions.
+
+void test1() {
+  var x = 6;
+  try {
+    throw x = 10;
+    x = 0;
+  } catch (e) {
+    Expect.equals(10, e);
+    Expect.equals(10, x);
+    x = 15;
+  }
+  Expect.equals(15, x);
+  x = 100;
+  try {
+    throw x++;
+    x = 0;
+  } catch (e) {
+    Expect.equals(100, e);
+    Expect.equals(101, x);
+    x = 150;
+  }
+  Expect.equals(150, x);
+}
+
+void test2() {
+  var x = 6;
+  try {
+    throw x + 4;
+  } catch (e) {
+    Expect.equals(10, e);
+    Expect.equals(6, x);
+    x = 15;
+  }
+  Expect.equals(15, x);
+}
+
+foo(x, y) => throw "foo" "$x";
+
+bar(x, y) => throw "foo" "${throw x}";
+
+class Q {
+  var qqq;
+  f(x) {
+    qqq = x;
+  }
+
+  Q get nono => throw "nono";
+}
+
+void test3() {
+  try {
+    throw throw throw "up";
+  } catch (e) {
+    Expect.equals("up", e);
+  }
+
+  dynamic x = 10;
+  try {
+    foo(x = 12, throw 7);
+  } catch (e) {
+    Expect.equals(7, e);
+    Expect.equals(12, x);
+  }
+
+  x = 10;
+  try {
+    foo(x++, 10);
+  } catch (e) {
+    Expect.equals("foo10", e);
+    Expect.equals(11, x);
+  }
+
+  x = 100;
+  try {
+    bar(++x, 10);
+  } catch (e) {
+    Expect.equals(101, e);
+    Expect.equals(101, x);
+  }
+
+  x = null;
+  try {
+    x = new Q();
+    x
+      ..f(11)
+      ..qqq = throw 77
+      ..f(22);
+  } catch (e) {
+    Expect.equals(77, e);
+    Expect.equals(11, x.qqq);
+  }
+}
+
+void test4() {
+  var q = new Q();
+  Expect.throws(() => q.nono, (e) => e == "nono");
+}
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+}
diff --git a/tests/language/exception/throw_test.dart b/tests/language/exception/throw_test.dart
new file mode 100644
index 0000000..0c864cc
--- /dev/null
+++ b/tests/language/exception/throw_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing throw statement
+
+import "package:expect/expect.dart";
+
+class MyException {
+  const MyException(String this.message_);
+  final String message_;
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = func();
+      if (j > 0) {
+        throw new MyException("Test for exception being thrown");
+      }
+    } on MyException catch (exception) {
+      i = 100;
+      print(exception.message_);
+    } finally {
+      i = i + 800;
+    }
+    return i;
+  }
+
+  static int func() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class ThrowTest {
+  static testMain() {
+    Expect.equals(900, Helper.f1(1));
+  }
+}
+
+main() {
+  ThrowTest.testMain();
+}
diff --git a/tests/language/exception/try_catch2_test.dart b/tests/language/exception/try_catch2_test.dart
new file mode 100644
index 0000000..8da606c
--- /dev/null
+++ b/tests/language/exception/try_catch2_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown. (Nested try/catch blocks).
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : message_ = message;
+  String getMessage() {
+    return message_;
+  }
+
+  final String message_;
+}
+
+class StackTrace {
+  StackTrace() {}
+}
+
+class Helper {
+  static int f1(int i) {
+    try {
+      int j;
+      j = f2();
+      i = i + 1;
+      try {
+        j = f2() + f3() + j;
+        i = i + 1;
+      } on TestException catch (e, trace) {
+        j = 50;
+      }
+      j = f3() + j;
+    } on MyException catch (exception) {
+      i = 100;
+    } on TestException catch (e, trace) {
+      i = 200;
+    }
+    return i;
+  }
+
+  static int f2() {
+    return 2;
+  }
+
+  static int f3() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class TryCatch2Test {
+  static testMain() {
+    Expect.equals(3, Helper.f1(1));
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatch2Test.testMain();
+  }
+}
diff --git a/tests/language/exception/try_catch3_test.dart b/tests/language/exception/try_catch3_test.dart
new file mode 100644
index 0000000..6cff3f8
--- /dev/null
+++ b/tests/language/exception/try_catch3_test.dart
@@ -0,0 +1,126 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+abstract class TestException {
+  String getMessage();
+}
+
+class MyException implements TestException {
+  const MyException([String message = ""]) : this._message = message;
+  String getMessage() {
+    return _message;
+  }
+
+  final String _message;
+}
+
+class MyParameterizedException<U, V> implements TestException {
+  const MyParameterizedException([String message = ""])
+      : this._message = message;
+  String getMessage() {
+    return _message;
+  }
+
+  final String _message;
+}
+
+class StackTrace {
+  StackTrace() {}
+  printStackTrace(TestException ex) {
+    print(ex);
+  }
+}
+
+class Helper {
+  static int test1(int i) {
+    try {
+      int j;
+      j = f2();
+      j = f3();
+      try {
+        int k = f2();
+        f3();
+      } on MyException catch (ex) {
+        int i = 10;
+        print(i);
+      } on TestException catch (ex) {
+        int k = 10;
+        print(k);
+      }
+      try {
+        j = j + 24;
+      } catch (e) {
+        i = 300;
+        print(e.getMessage());
+      }
+      try {
+        j += 20;
+      } catch (e) {
+        i = 400;
+        print(e.getMessage());
+      }
+      try {
+        j += 40;
+      } catch (e) {
+        i = 600;
+        print(e.getMessage());
+      }
+      try {
+        j += 60;
+      } catch (e, trace) {
+        i = 700;
+        print(trace.toString());
+        print(e.getMessage());
+      }
+      try {
+        j += 80;
+      } on MyException catch (e) {
+        i = 500;
+        print(e.getMessage());
+      }
+    } on MyParameterizedException<String, TestException> catch (e, trace) {
+      i = 800;
+      print(trace.toString());
+      rethrow;
+    } on MyException catch (exception) {
+      i = 100;
+      print(exception.getMessage());
+    } on TestException catch (e, trace) {
+      i = 200;
+      print(trace.toString());
+    } finally {
+      i = 900;
+    }
+    return i;
+  }
+
+  static int f2() {
+    return 2;
+  }
+
+  static int f3() {
+    int i = 0;
+    while (i < 10) {
+      i++;
+    }
+    return i;
+  }
+}
+
+class TryCatchTest {
+  static testMain() {
+    Expect.equals(900, Helper.test1(1));
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatchTest.testMain();
+  }
+}
diff --git a/tests/language/exception/try_catch4_test.dart b/tests/language/exception/try_catch4_test.dart
new file mode 100644
index 0000000..a6cbe03
--- /dev/null
+++ b/tests/language/exception/try_catch4_test.dart
@@ -0,0 +1,206 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that our SSA graph does have the try body a predecessor of a
+// try/finally.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo1() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      return false;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+doThrow() {
+  throw 2;
+}
+
+foo2() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      doThrow();
+      return false;
+    } catch (e) {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo3() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      doThrow();
+    } catch (e) {
+      a = 8;
+      entered = true;
+      return false;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo4() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      break;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo5() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      doThrow();
+      break;
+    } catch (e) {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo6() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      doThrow();
+    } catch (e) {
+      a = 8;
+      entered = true;
+      break;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo7() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      continue;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo8() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      a = 8;
+      doThrow();
+      continue;
+    } catch (e) {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+foo9() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      doThrow();
+    } catch (e) {
+      a = 8;
+      entered = true;
+      continue;
+    } finally {
+      b = 8 == a;
+      entered = true;
+      continue;
+    }
+  }
+}
+
+main_test() {
+  a = 0;
+  Expect.isTrue(foo1());
+  a = 0;
+  Expect.isTrue(foo2());
+  a = 0;
+  Expect.isTrue(foo3());
+  a = 0;
+  Expect.isTrue(foo4());
+  a = 0;
+  Expect.isTrue(foo5());
+  a = 0;
+  Expect.isTrue(foo6());
+  a = 0;
+  Expect.isTrue(foo7());
+  a = 0;
+  Expect.isTrue(foo8());
+  a = 0;
+  Expect.isTrue(foo9());
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    main_test();
+  }
+}
diff --git a/tests/language/exception/try_catch5_test.dart b/tests/language/exception/try_catch5_test.dart
new file mode 100644
index 0000000..6920b06
--- /dev/null
+++ b/tests/language/exception/try_catch5_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Check that our SSA graph does have the try body a predecessor of a
+// try/finally.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var a;
+
+foo1() {
+  var b = false;
+  var entered = false;
+  while (true) {
+    if (entered) return b;
+    b = 8 == a; // This expression should not be GVN'ed.
+    try {
+      try {
+        a = 8;
+        return false;
+      } finally {
+        b = 8 == a;
+        entered = true;
+        continue;
+      }
+    } finally {
+      continue;
+    }
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    a = 0;
+    Expect.isTrue(foo1());
+  }
+}
diff --git a/tests/language/exception/try_catch_on_syntax_test.dart b/tests/language/exception/try_catch_on_syntax_test.dart
new file mode 100644
index 0000000..c19a94f
--- /dev/null
+++ b/tests/language/exception/try_catch_on_syntax_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+void test1() {
+  var foo = 0;
+  try {
+    throw new MyException1();
+  }
+  on on MyException2 catch (e) { } //# 02: syntax error
+  catch MyException2 catch (e) { } //# 03: syntax error
+  catch catch catch (e) { } //# 04: syntax error
+  on (e) { } //# 05: syntax error
+  catch MyException2 catch (e) { } //# 06: syntax error
+  on MyException2 catch (e) {
+    foo = 1;
+  } on MyException1 catch (e) {
+    foo = 2;
+  } on MyException catch (e) {
+    foo = 3;
+  }
+  on UndefinedClass //# 07: compile-time error
+  catch (e) {
+    foo = 4;
+  }
+  Expect.equals(2, foo);
+}
+
+testFinal() {
+  try {
+    throw "catch this!";
+  } catch (e, s) {
+    // Test that the error and stack trace variables are final.
+      e = null; // //# 10: compile-time error
+      s = null; // //# 11: compile-time error
+  }
+}
+
+main() {
+  test1();
+  testFinal();
+}
diff --git a/tests/language/exception/try_catch_optimized1_test.dart b/tests/language/exception/try_catch_optimized1_test.dart
new file mode 100644
index 0000000..c3b522a
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized1_test.dart
@@ -0,0 +1,290 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+maythrow(x) {
+  if (x == null) throw 42;
+  return 99;
+}
+
+f1(x) {
+  var result = 123;
+  try {
+    result = maythrow(x);
+    if (result > 100) throw 42;
+  } catch (e) {
+    Expect.equals(result, 123);
+    Expect.equals(42, e);
+    result = 0;
+  }
+  return result;
+}
+
+class A {
+  maythrow(x) {
+    if (x == null) throw 42;
+    return 99;
+  }
+}
+
+f2(x) {
+  dynamic result = 123;
+  var a = new A();
+  try {
+    result++;
+    result = a.maythrow(x);
+  } catch (e) {
+    Expect.equals(124, result);
+    result = x;
+  }
+  return result;
+}
+
+f3(x, y) {
+  var result = 123;
+  var a = new A();
+  try {
+    result++;
+    result = a.maythrow(x);
+  } catch (e) {
+    result = y + 1; // Deopt on overflow
+  }
+  return result;
+}
+
+f4(x) {
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f4(e, "abc");
+  }
+}
+
+check_f4(e, s) {
+  if (e != 42) throw "ERROR";
+  if (s != "abc") throw "ERROR";
+}
+
+f5(x) {
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f5(e, "abc");
+  }
+
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f5(e, "abc");
+  }
+}
+
+check_f5(e, s) {
+  if (e != 42) throw "ERROR";
+  if (s != "abc") throw "ERROR";
+}
+
+f6(x, y) {
+  var a = x;
+  var b = y;
+  var c = 123;
+  check_f6(42, null, 1, 123, null, 1);
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f6(e, a, b, c, x, y);
+  }
+}
+
+check_f6(e, a, b, c, x, y) {
+  if (e != 42) throw "ERROR";
+  if (a != null) throw "ERROR";
+  if (b != 1) throw "ERROR";
+  if (c != 123) throw "ERROR";
+  if (x != null) throw "ERROR";
+  if (y != 1) throw "ERROR";
+}
+
+bool f7(String str) {
+  double d = double.parse(str);
+  var t = d;
+  try {
+    var a = d.toInt();
+    return false;
+  } on UnsupportedError catch (e) {
+    Expect.equals(true, identical(t, d));
+    return true;
+  }
+}
+
+f8(x, [a = 3, b = 4]) {
+  var c = 123;
+  var y = a;
+  try {
+    maythrow(x);
+  } catch (e, s) {
+    check_f8(e, s, a, b, c, x, y);
+  }
+}
+
+check_f8(e, s, a, b, c, x, y) {
+  if (e != 42) throw "ERROR";
+  if (s is! StackTrace) throw "ERROR";
+  if (a != 3) {
+    print(a);
+    throw "ERROR";
+  }
+  if (b != 4) throw "ERROR";
+  if (c != 123) throw "ERROR";
+  if (x != null) throw "ERROR";
+  if (y != a) throw "ERROR";
+}
+
+f9(x, [a = 3, b = 4]) {
+  var c = 123;
+  var y = a;
+  try {
+    if (x < a) maythrow(null);
+    maythrow(x);
+  } catch (e, s) {
+    check_f9(e, s, a, b, c, x, y);
+  }
+}
+
+check_f9(e, s, a, b, c, x, y) {
+  if (e != 42) throw "ERROR";
+  if (s is! StackTrace) throw "ERROR";
+  if (a != 3) {
+    print(a);
+    throw "ERROR";
+  }
+  if (b != 4) throw "ERROR";
+  if (c != 123) throw "ERROR";
+  if (x != null) throw "ERROR";
+  if (y != a) throw "ERROR";
+}
+
+f10(x, y) {
+  var result = 123;
+  try {
+    result = maythrow(x);
+  } catch (e) {
+    Expect.equals(123, result);
+    Expect.equals(0.5, y / 2.0);
+    result = 0;
+  }
+  return result;
+}
+
+f11(x) {
+  var result = 123;
+  var tmp = x;
+  try {
+    result = maythrow(x);
+    if (result > 100) throw 42;
+  } catch (e, s) {
+    Expect.equals(123, result);
+    Expect.equals(true, identical(tmp, x));
+    Expect.equals(true, s is StackTrace);
+    result = 0;
+  }
+  return result;
+}
+
+f12([x = null]) {
+  try {
+    maythrow(x);
+  } catch (e) {
+    check_f12(e, x);
+  }
+}
+
+check_f12(e, x) {
+  if (e != 42) throw "ERROR";
+  if (x != null) throw "ERROR";
+}
+
+f13(x) {
+  var result = 123;
+  try {
+    try {
+      result = maythrow(x);
+      if (result > 100) throw 42;
+    } catch (e) {
+      Expect.equals(123, result);
+      result = 0;
+    }
+    maythrow(x);
+  } catch (e) {
+    result++;
+  }
+  return result;
+}
+
+main() {
+  for (var i = 0; i < 20; i++) f1("abc");
+  Expect.equals(99, f1("abc"));
+  Expect.equals(0, f1(null));
+
+  for (var i = 0; i < 20; i++) f2("abc");
+  Expect.equals(99, f2("abc"));
+  Expect.equals(null, f2(null));
+
+  f3("123", 0);
+  for (var i = 0; i < 20; i++) f3(null, 0);
+  Expect.equals(99, f3("123", 0));
+  Expect.equals(0x40000000, f3(null, 0x3fffffff));
+
+  f4(null);
+  for (var i = 0; i < 20; i++) f4(123);
+  f4(null);
+
+  f5(null);
+  for (var i = 0; i < 20; i++) f5(123);
+  f5(null);
+
+  f6(null, 1);
+  for (var i = 0; i < 20; i++) f6(123, 1);
+  f6(null, 1);
+
+  f7("1.2");
+  f7("Infinity");
+  f7("-Infinity");
+  for (var i = 0; i < 20; i++) f7("1.2");
+  Expect.equals(false, f7("1.2"));
+  Expect.equals(true, f7("Infinity"));
+  Expect.equals(true, f7("-Infinity"));
+  Expect.equals(false, f7("123456789012345")); // Deopt.
+  for (var i = 0; i < 20; i++) f7("123456789012345");
+  Expect.equals(true, f7("Infinity"));
+  Expect.equals(true, f7("-Infinity"));
+
+  for (var i = 0; i < 20; i++) f8(null);
+  f8(null);
+
+  f9(5);
+  f9(5.0);
+  for (var i = 0; i < 20; i++) f9(3);
+  f9(3);
+
+  var y = 1.0;
+  Expect.equals(0, f10(null, y));
+  for (var i = 0; i < 20; i++) f10("abc", y);
+  Expect.equals(99, f10("abc", y));
+  Expect.equals(0, f10(null, y));
+
+  for (var i = 0; i < 20; i++) f11("abc");
+  Expect.equals(99, f11("abc"));
+  Expect.equals(0, f11(null));
+
+  for (var i = 0; i < 20; i++) f12(null);
+  f12(null);
+
+  f13(null);
+  for (var i = 0; i < 20; i++) f13("abc");
+  Expect.equals(99, f13("abc"));
+  Expect.equals(1, f13(null));
+}
diff --git a/tests/language/exception/try_catch_optimized2_test.dart b/tests/language/exception/try_catch_optimized2_test.dart
new file mode 100644
index 0000000..159a6e5
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized2_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test allocation sinking with optimized try-catch.
+
+bar() {
+  // Should not be inlined.
+  try {} finally {}
+}
+
+foo(List<int> a) {
+  var r = 0;
+  for (var i in a) {
+    r += i;
+  }
+  try {
+    bar();
+  } finally {}
+  return r;
+}
+
+main() {
+  var a = [1, 2, 3];
+  for (var i = 0; i < 20; i++) foo(a);
+  Expect.equals(6, foo(a));
+}
diff --git a/tests/language/exception/try_catch_optimized3_test.dart b/tests/language/exception/try_catch_optimized3_test.dart
new file mode 100644
index 0000000..a2b03fc
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized3_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test unboxed double operations inside try-catch.
+foo(bool b) {
+  if (b) throw 123;
+}
+
+test_double(double x, bool b) {
+  try {
+    x += 1.0;
+    foo(b);
+  } catch (e) {
+    var result = x - 1.0;
+    Expect.equals(1.0, result);
+    return result;
+  }
+}
+
+main() {
+  for (var i = 0; i < 100; i++) test_double(1.0, false);
+  test_double(1.0, false);
+  Expect.equals(1.0, test_double(1.0, true));
+}
diff --git a/tests/language/exception/try_catch_optimized4_test.dart b/tests/language/exception/try_catch_optimized4_test.dart
new file mode 100644
index 0000000..dc98f31
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized4_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Test correct dead phi elimination with try catch.
+
+List<Object> a = [1, 2, 3, 4, 5];
+
+class MyError {}
+
+class M {
+  maythrow(i) {
+    try {
+      if (i <= 5) throw new MyError();
+    } catch (e) {
+      throw e;
+    }
+  }
+}
+
+loop_test() {
+  bool failed = false;
+  M m = new M();
+  for (Object i in a) {
+    try {
+      String res = m.maythrow(i);
+      failed = true;
+    } on MyError catch (e) {}
+    if (!identical(failed, false)) {
+      Expect.fail("");
+    }
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) loop_test();
+}
diff --git a/tests/language/exception/try_catch_optimized5_test.dart b/tests/language/exception/try_catch_optimized5_test.dart
new file mode 100644
index 0000000..a3b7b99
--- /dev/null
+++ b/tests/language/exception/try_catch_optimized5_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
+
+// Test optional parameters updated inside try-catch
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+m1(int b) {
+  if (b == 1) throw 123;
+}
+
+@pragma('vm:never-inline')
+m2(int b) {
+  if (b == 2) throw 456;
+}
+
+@pragma('vm:never-inline')
+test1(int b, [int state = 0]) {
+  try {
+    state++;
+    m1(b);
+    state++;
+    m2(b);
+    state++;
+  } catch (e, s) {
+    if (b == 1 && state != 1) throw "fail1";
+    if (b == 2 && state != 2) throw "fail2";
+    if (b == 3 && state != 3) throw "fail3";
+    if (s is! StackTrace) throw "fail4";
+    return e;
+  }
+  return "no throw";
+}
+
+@pragma('vm:never-inline')
+test2(int b, [int state = -1]) {
+  state = 0;
+  try {
+    state++;
+    m1(b);
+    state++;
+    m2(b);
+    state++;
+  } catch (e, s) {
+    if (b == 1 && state != 1) throw "fail1";
+    if (b == 2 && state != 2) throw "fail2";
+    if (b == 3 && state != 3) throw "fail3";
+    if (s is! StackTrace) throw "fail4";
+    return e;
+  }
+  return "no throw";
+}
+
+main() {
+  for (var i = 0; i < 300; i++) {
+    Expect.equals("no throw", test1(0));
+  }
+  Expect.equals("no throw", test1(0));
+  Expect.equals(123, test1(1));
+  Expect.equals(456, test1(2));
+
+  for (var i = 0; i < 300; i++) {
+    Expect.equals("no throw", test2(0));
+  }
+  Expect.equals("no throw", test2(0));
+  Expect.equals(123, test2(1));
+  Expect.equals(456, test2(2));
+}
diff --git a/tests/language/exception/try_catch_osr_test.dart b/tests/language/exception/try_catch_osr_test.dart
new file mode 100644
index 0000000..345f764
--- /dev/null
+++ b/tests/language/exception/try_catch_osr_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+// Test OSR in different places of a try-catch.
+
+import "package:expect/expect.dart";
+
+maythrow(x) {
+  try {
+    if (x == null) throw 42;
+    return 99;
+  } finally {}
+}
+
+f1() {
+  var s = 0, t = "abc";
+  for (var i = 0; i < 21; ++i) {
+    s += i;
+  }
+  try {
+    maythrow(null);
+  } catch (e) {
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    s++;
+  }
+  return s;
+}
+
+f2([int x = 1]) {
+  var s = 0;
+  var t = "abc";
+  try {
+    try {
+      for (var i = 0; i < 20; ++i) {
+        if (i == 18) maythrow(null);
+        s += x;
+      }
+    } catch (e) {
+      Expect.equals(1, x);
+      Expect.equals("abc", t);
+      Expect.equals(42, e);
+      s++;
+    }
+  } catch (e) {}
+  return s;
+}
+
+f3() {
+  var s = 0, t = "abc";
+  try {
+    maythrow(null);
+  } catch (e) {
+    Expect.equals("abc", t);
+    for (var i = 0; i < 21; ++i) {
+      s += i;
+    }
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    return s;
+  }
+}
+
+f4() {
+  var s = 0, t = "abc";
+  try {
+    for (var i = 0; i < 21; ++i) {
+      if (i == 18) maythrow(null);
+      s += i;
+    }
+  } catch (e) {
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    s++;
+  }
+  return s;
+}
+
+f5() {
+  var s, t = "abc";
+  try {
+    maythrow(null);
+  } catch (e) {
+    Expect.equals("abc", t);
+    Expect.equals(42, e);
+    s = 0;
+  }
+  for (var i = 0; i < 21; ++i) {
+    s += i;
+  }
+  Expect.equals("abc", t);
+  return s;
+}
+
+main() {
+  Expect.equals(211, f1());
+  Expect.equals(19, f2());
+  Expect.equals(210, f3());
+  Expect.equals(9 * 17 + 1, f4());
+  Expect.equals(210, f5());
+}
diff --git a/tests/language/exception/try_catch_regress_27483_test.dart b/tests/language/exception/try_catch_regress_27483_test.dart
new file mode 100644
index 0000000..dde7246
--- /dev/null
+++ b/tests/language/exception/try_catch_regress_27483_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation
+
+// Test local variables updated inside try-catch.
+
+import "package:expect/expect.dart";
+
+@pragma('vm:never-inline')
+m1(int b) {
+  if (b == 1) throw 123;
+}
+
+@pragma('vm:never-inline')
+m2(int b) {
+  if (b == 2) throw 456;
+}
+
+@pragma('vm:never-inline')
+test(b) {
+  var state = 0;
+  try {
+    state++;
+    m1(b);
+    state++;
+    m2(b);
+    state++;
+  } catch (e, s) {
+    if (b == 1 && state != 1) throw "fail1";
+    if (b == 2 && state != 2) throw "fail2";
+    if (b == 3 && state != 3) throw "fail3";
+    return e;
+  }
+  return "no throw";
+}
+
+main() {
+  for (var i = 0; i < 300; i++) {
+    Expect.equals("no throw", test(0));
+  }
+  Expect.equals("no throw", test(0));
+  Expect.equals(123, test(1));
+  Expect.equals(456, test(2));
+}
diff --git a/tests/language/exception/try_catch_runtime_test.dart b/tests/language/exception/try_catch_runtime_test.dart
new file mode 100644
index 0000000..872f9d7
--- /dev/null
+++ b/tests/language/exception/try_catch_runtime_test.dart
@@ -0,0 +1,199 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+class TryCatchTest {
+  static void test1() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test2() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException catch (e) {
+      foo = 2;
+    } on MyException1 catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test3() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test4() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } on MyException catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test5() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } catch (e) {
+      foo = 2;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test6() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test7() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test8() {
+    var e = 3;
+    var caught = false;
+    try {
+      throw new MyException();
+    } catch (exc) {
+      caught = true;
+    }
+    Expect.equals(true, caught);
+    Expect.equals(3, e);
+  }
+
+  static void test9() {
+    dynamic e = 6;
+    try {
+      throw "up";
+    } on String {
+      e = "s";
+    } on int {
+      e = "i";
+    }
+    Expect.equals("s", e);
+  }
+
+  static void test10() {
+    try {
+      throw "up";
+    } on String catch (e) {
+      var e = 1; // ok, shadows exception variable.
+      Expect.equals(1, e);
+    }
+  }
+
+  static void test11() {
+    var e0 = 11;
+    try {
+      throw "up";
+    } on int catch (e0) {
+      Expect.fail("unreachable");
+    } on String catch (e1) {
+      // e0 from the other catch clause is not in scope.
+      Expect.equals(11, e0);
+    }
+  }
+
+  static void test12() {
+    const x = const [];
+    try {
+      throw "up";
+    } catch (e) {
+      Expect.equals("up", e);
+    } on String catch (e) {
+      // Compile-time constants in unreachable catch blocks are still
+      // compiled.
+
+      Expect.fail("unreachable");
+    }
+  }
+
+  static void testMain() {
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    test12();
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatchTest.testMain();
+  }
+}
diff --git a/tests/language/exception/try_catch_syntax_test.dart b/tests/language/exception/try_catch_syntax_test.dart
new file mode 100644
index 0000000..5a192d1
--- /dev/null
+++ b/tests/language/exception/try_catch_syntax_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  testMissingCatch();
+  testMissingTry();
+  testDuplicateCatchVariable();
+  testIllegalFinally();
+  testIllegalCatch();
+  testIllegalRethrow();
+}
+
+testMissingCatch() {
+  try { } // //# 01: syntax error
+}
+
+testMissingTry() {
+  on Exception catch (e) { } //                  //# 02: syntax error
+  on Exception catch (e, trace) { } //           //# 03: syntax error
+  finally { } //                                 //# 04: syntax error
+}
+
+testDuplicateCatchVariable() {
+  try { } on Exception catch (e, e) { } //# 05: compile-time error
+}
+
+testIllegalFinally() {
+  try { } finally (e) { } //# 06: syntax error
+}
+
+testIllegalCatch() {
+  try { } catch () { } //             //# 07: syntax error
+  try { } on MammaMia catch (e) { } //# 08: compile-time error
+  try { } catch (var e) { } //        //# 09: syntax error
+  try { } catch (final e) { } //      //# 10: syntax error
+  try { } catch (int e) { } //        //# 11: syntax error
+  try { } catch (final int e) { } //  //# 12: syntax error
+  try { } catch ([e, s]) { } //       //# 13: syntax error
+  try { } catch (e, [s]) { } //       //# 14: syntax error
+  try { } catch (e, [s0, s1]) { } //  //# 15: syntax error
+}
+
+testIllegalRethrow() {
+  try { rethrow; } catch (e) { } //            //# 16: compile-time error
+  try { } catch (e) { } finally { rethrow; } //# 17: compile-time error
+}
diff --git a/tests/language/exception/try_catch_test.dart b/tests/language/exception/try_catch_test.dart
new file mode 100644
index 0000000..2b8fee2
--- /dev/null
+++ b/tests/language/exception/try_catch_test.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+class MyException {}
+
+class MyException1 extends MyException {}
+
+class MyException2 extends MyException {}
+
+class TryCatchTest {
+  static void test1() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test2() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException catch (e) {
+      foo = 2;
+    } on MyException1 catch (e) {
+      foo = 3;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test3() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } on MyException catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test4() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } on MyException catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test5() {
+    var foo = 0;
+    try {
+      throw new MyException1();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } catch (e) {
+      foo = 2;
+    }
+    Expect.equals(2, foo);
+  }
+
+  static void test6() {
+    var foo = 0;
+    try {
+      throw new MyException();
+    } on MyException2 catch (e) {
+      foo = 1;
+    } on MyException1 catch (e) {
+      foo = 2;
+    } catch (e) {
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test7() {
+    var foo = 0;
+    try {
+      try {
+        throw new MyException();
+      } on MyException2 catch (e) {
+        foo = 1;
+      } on MyException1 catch (e) {
+        foo = 2;
+      }
+    } catch (e) {
+      Expect.equals(0, foo);
+      foo = 3;
+    }
+    Expect.equals(3, foo);
+  }
+
+  static void test8() {
+    var e = 3;
+    var caught = false;
+    try {
+      throw new MyException();
+    } catch (exc) {
+      caught = true;
+    }
+    Expect.equals(true, caught);
+    Expect.equals(3, e);
+  }
+
+  static void test9() {
+    dynamic e = 6;
+    try {
+      throw "up";
+    } on String {
+      e = "s";
+    } on int {
+      e = "i";
+    }
+    Expect.equals("s", e);
+  }
+
+  static void test10() {
+    try {
+      throw "up";
+    } on String catch (e) {
+      var e = 1; // ok, shadows exception variable.
+      Expect.equals(1, e);
+    }
+  }
+
+  static void test11() {
+    var e0 = 11;
+    try {
+      throw "up";
+    } on int catch (e0) {
+      Expect.fail("unreachable");
+    } on String catch (e1) {
+      // e0 from the other catch clause is not in scope.
+      Expect.equals(11, e0);
+    }
+  }
+
+  static void test12() {
+    const x = const [];
+    try {
+      throw "up";
+    } catch (e) {
+      Expect.equals("up", e);
+    } on String catch (e) {
+      // Compile-time constants in unreachable catch blocks are still
+      // compiled.
+      const y = x[0];
+      //        ^^^^
+      // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+      //         ^
+      // [cfe] Constant evaluation error:
+      Expect.fail("unreachable");
+    }
+  }
+
+  static void testMain() {
+    test1();
+    test2();
+    test3();
+    test4();
+    test5();
+    test6();
+    test7();
+    test8();
+    test9();
+    test10();
+    test11();
+    test12();
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    TryCatchTest.testMain();
+  }
+}
diff --git a/tests/language/exception/try_finally_regress_25333_test.dart b/tests/language/exception/try_finally_regress_25333_test.dart
new file mode 100644
index 0000000..6318f7c
--- /dev/null
+++ b/tests/language/exception/try_finally_regress_25333_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test correct handling of try-catch inside try-finally.
+
+import "package:expect/expect.dart";
+
+void main() {
+  print("== test1 ==");
+  bool caught = false;
+  try {
+    test1();
+    print("Unexpected 1"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 1: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+  print("== test2 ==");
+  caught = false;
+  try {
+    test2();
+    print("Unexpected 2"); // should never go here
+    Expect.isTrue(false);
+  } catch (e) {
+    caught = true;
+    print("main catch 2: $e");
+    Expect.equals(e, "Ball");
+  }
+  Expect.isTrue(caught);
+}
+
+void test1() {
+  try {
+    throw "Ball";
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch (e) {
+      print("test 1 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+void test2() {
+  try {
+    throwError(); // call a method that throws an error
+  } finally {
+    try {
+      throw "Frisbee";
+    } catch (e) {
+      print("test 2 catch: $e");
+      Expect.equals(e, "Frisbee");
+    }
+  }
+}
+
+void throwError() {
+  throw "Ball";
+}
diff --git a/tests/language/exception/try_finally_regress_25654_test.dart b/tests/language/exception/try_finally_regress_25654_test.dart
new file mode 100644
index 0000000..32a236f
--- /dev/null
+++ b/tests/language/exception/try_finally_regress_25654_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test break out of try-finally.
+
+import "package:expect/expect.dart";
+
+var count = 0;
+
+test() {
+  L:
+  while (true) {
+    try {
+      break L;
+    } finally {
+      count++;
+    }
+  }
+  throw "ex";
+}
+
+main() {
+  bool caught = false;
+  try {
+    test();
+  } catch (e) {
+    caught = true;
+    Expect.equals(e, "ex");
+  }
+  Expect.isTrue(caught);
+  Expect.equals(1, count);
+}