Roll Kernel to fix an async bug.

There was a bug in the translation of await in finally when there
was a return in the try block.

The new async/async* translation revealed a bug in the scoping of
labels.  Labels from enclosing functions were visible in nested
functions.  That bug is fixed here.

BUG=
[email protected]

Review URL: https://chromereviews.googleplex.com/536237014 .
diff --git a/DEPS b/DEPS
index 309453a..0c9ae31 100644
--- a/DEPS
+++ b/DEPS
@@ -57,7 +57,7 @@
   "dart_style_tag": "@0.2.9+1",
   "dartdoc_tag" : "@v0.9.7+3",
   "fixnum_tag": "@0.10.5",
-  "kernel_rev": "@480abf7604fd64b96bd4b974352db034179f413a",
+  "kernel_rev": "@290f955760a219902e4d5b716668bff29711d1ab",
   "func_tag": "@0.1.0",
   "glob_tag": "@1.1.3",
   "html_tag" : "@0.13.0",
diff --git a/runtime/vm/dil_binary.cc b/runtime/vm/dil_binary.cc
index 7eaeb13..dbc88b5 100644
--- a/runtime/vm/dil_binary.cc
+++ b/runtime/vm/dil_binary.cc
@@ -390,25 +390,45 @@
   T* builder_;
 };
 
+// Unlike other scopes, labels from enclosing functions are not visible in
+// nested functions.  The LabelScope class is used to hide outer labels.
+template<typename Builder, typename Block>
+class LabelScope {
+ public:
+  explicit LabelScope(Builder* builder) : builder_(builder) {
+    outer_block_ = builder_->labels();
+    builder_->set_labels(&block_);
+  }
+  ~LabelScope() {
+    builder_->set_labels(outer_block_);
+  }
+
+ private:
+  Builder* builder_;
+  Block block_;
+  Block* outer_block_;
+};
+
 class ReaderHelper {
  public:
-  ReaderHelper() : program_(NULL) {}
-  ~ReaderHelper() {}
+  ReaderHelper() : program_(NULL), labels_(NULL) {}
 
   Program* program() { return program_; }
   void set_program(Program* program) { program_ = program; }
 
   BlockStack<VariableDeclaration>& variables() { return scope_; }
   BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
-  BlockStack<LabeledStatement>& lables() { return labels_; }
   BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }
 
+  BlockStack<LabeledStatement>* labels() { return labels_; }
+  void set_labels(BlockStack<LabeledStatement>* labels) { labels_ = labels; }
+
  private:
   Program* program_;
   BlockStack<VariableDeclaration> scope_;
   BlockStack<TypeParameter> type_parameters_;
-  BlockStack<LabeledStatement> labels_;
   BlockStack<SwitchCase> switch_cases_;
+  BlockStack<LabeledStatement>* labels_;
 };
 
 class Reader {
@@ -533,6 +553,8 @@
 
 class WriterHelper {
  public:
+  WriterHelper() : labels_(NULL) {}
+
   void SetProgram(Program* program) {
     program_ = program;
     for (int i = 0; i < program->libraries().length(); i++) {
@@ -580,9 +602,11 @@
 
   BlockMap<VariableDeclaration>& variables() { return scope_; }
   BlockMap<TypeParameter>& type_parameters() { return type_parameters_; }
-  BlockMap<LabeledStatement>& lables() { return labels_; }
   BlockMap<SwitchCase>& switch_cases() { return switch_cases_; }
 
+  BlockMap<LabeledStatement>* labels() { return labels_; }
+  void set_labels(BlockMap<LabeledStatement>* labels) { labels_ = labels; }
+
  private:
   Program* program_;
 
@@ -595,8 +619,8 @@
 
   BlockMap<VariableDeclaration> scope_;
   BlockMap<TypeParameter> type_parameters_;
-  BlockMap<LabeledStatement> labels_;
   BlockMap<SwitchCase> switch_cases_;
+  BlockMap<LabeledStatement>* labels_;
 };
 
 class Writer {
@@ -2213,31 +2237,31 @@
 LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   LabeledStatement* stmt = new LabeledStatement();
-  reader->helper()->lables().Push(stmt);
+  reader->helper()->labels()->Push(stmt);
   stmt->body_ = Statement::ReadFrom(reader);
-  reader->helper()->lables().Pop(stmt);
+  reader->helper()->labels()->Pop(stmt);
   return stmt;
 }
 
 void LabeledStatement::WriteTo(Writer* writer) {
   TRACE_WRITE_OFFSET();
   writer->WriteTag(kLabeledStatement);
-  writer->helper()->lables().Push(this);
+  writer->helper()->labels()->Push(this);
   body_->WriteTo(writer);
-  writer->helper()->lables().Pop(this);
+  writer->helper()->labels()->Pop(this);
 }
 
 BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
   TRACE_READ_OFFSET();
   BreakStatement* stmt = new BreakStatement();
-  stmt->target_ = reader->helper()->lables().Lookup(reader->ReadUInt());
+  stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt());
   return stmt;
 }
 
 void BreakStatement::WriteTo(Writer* writer) {
   TRACE_WRITE_OFFSET();
   writer->WriteTag(kBreakStatement);
-  writer->WriteUInt(writer->helper()->lables().Lookup(target_));
+  writer->WriteUInt(writer->helper()->labels()->Lookup(target_));
 }
 
 WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
@@ -2750,6 +2774,8 @@
   function->return_type_ = DartType::ReadFrom(reader);
   function->inferred_return_value_ = reader->ReadOptional<InferredValue>();
 
+  LabelScope<ReaderHelper, BlockStack<LabeledStatement> > labels(
+      reader->helper());
   VariableScope<ReaderHelper> vars(reader->helper());
   function->body_ = reader->ReadOptional<Statement>();
   return function;
@@ -2767,6 +2793,8 @@
   return_type_->WriteTo(writer);
   writer->WriteOptional<InferredValue>(inferred_return_value_);
 
+  LabelScope<WriterHelper, BlockMap<LabeledStatement> > labels(
+      writer->helper());
   VariableScope<WriterHelper> vars(writer->helper());
   writer->WriteOptional<Statement>(body_);
 }
diff --git a/tests/language/async_await_test.dart b/tests/language/async_await_test.dart
index 88fc1a5..b5f6c00 100644
--- a/tests/language/async_await_test.dart
+++ b/tests/language/async_await_test.dart
@@ -807,22 +807,20 @@
       return expect42(f());
     });
 
-    // Fails (x is 0, not 37) due to incorrect placement of inlined finally code
-    // (not in the future).
-    // test("await in finally", () {
-    //   var x = 0;
-    //   f() async {
-    //     try {
-    //       return id(42);
-    //     } finally {
-    //       x = await new Future.value(37);
-    //     }
-    //   }
-    //   return f().then((v) {
-    //     expect(v, equals(42));
-    //     expect(x, equals(37));
-    //   });
-    // });
+    test("await in finally", () {
+      var x = 0;
+      f() async {
+        try {
+          return id(42);
+        } finally {
+          x = await new Future.value(37);
+        }
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
 
     test("await err in body", () {
       f() async {
@@ -872,34 +870,34 @@
       return expect42(f());
     });
 
-    // test("await in body, override in finally", () {
-    //   f() async {
-    //     label: try {
-    //       return await new Future.value(37);
-    //     } finally {
-    //       break label;
-    //     }
-    //     return id(42);
-    //   }
-    //   return expect42(f());
-    // });
+    test("await in body, override in finally", () {
+      f() async {
+        label: try {
+          return await new Future.value(37);
+        } finally {
+          break label;
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
 
-    // test("await, override in finally", () {
-    //   var x = 0;
-    //   f() async {
-    //     label: try {
-    //       return 87;
-    //     } finally {
-    //       x = await new Future.value(37);
-    //       break label;
-    //     }
-    //     return id(42);
-    //   }
-    //   return f().then((v) {
-    //     expect(v, equals(42));
-    //     expect(x, equals(37));
-    //   });
-    // });
+    test("await, override in finally", () {
+      var x = 0;
+      f() async {
+        label: try {
+          return 87;
+        } finally {
+          x = await new Future.value(37);
+          break label;
+        }
+        return id(42);
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
 
     test("throw in body, await, override in finally 3", () {
       var x = 0;
@@ -930,19 +928,19 @@
       return expect42(f());
     });
 
-    // test("await in body, no-exit in finally", () {
-    //   f() async {
-    //     for (int i = 0; i < 10; i++) {
-    //       try {
-    //         return await i;
-    //       } finally {
-    //         continue;
-    //       }
-    //     }
-    //     return id(42);
-    //   }
-    //   return expect42(f());
-    // });
+    test("await in body, no-exit in finally", () {
+      f() async {
+        for (int i = 0; i < 10; i++) {
+          try {
+            return await i;
+          } finally {
+            continue;
+          }
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
 
     test("no-exit after await in finally", () {
       f() async {
@@ -980,54 +978,54 @@
       });
     });
 
-    // test("no-exit before await in finally 2", () {
-    //   f() async {
-    //     for (int i = 0; i < 10; i++) {
-    //       try {
-    //         return i;
-    //       } finally {
-    //         if (i >= 0) continue;
-    //         await new Future.value(42);
-    //       }
-    //     }
-    //     return id(42);
-    //   }
-    //   return expect42(f());
-    // });
+    test("no-exit before await in finally 2", () {
+      f() async {
+        for (int i = 0; i < 10; i++) {
+          try {
+            return i;
+          } finally {
+            if (i >= 0) continue;
+            await new Future.value(42);
+          }
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
 
-    // test("no-exit after await in finally", () {
-    //   f() async {
-    //     for (int i = 0; i < 10; i++) {
-    //       try {
-    //         return i;
-    //       } finally {
-    //         await new Future.value(42);
-    //         continue;
-    //       }
-    //     }
-    //     return id(42);
-    //   }
-    //   return expect42(f());
-    // });
+    test("no-exit after await in finally", () {
+      f() async {
+        for (int i = 0; i < 10; i++) {
+          try {
+            return i;
+          } finally {
+            await new Future.value(42);
+            continue;
+          }
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
 
-    // test("nested finallies", () {
-    //   var x = 0;
-    //   f() async {
-    //     try {
-    //       try {
-    //         return 42;
-    //       } finally {
-    //         x = await new Future.value(37);
-    //       }
-    //     } finally {
-    //       x += await new Future.value(37);
-    //     }
-    //   }
-    //   return f().then((v) {
-    //     expect(v, equals(42));
-    //     expect(x, equals(74));
-    //   });
-    // });
+    test("nested finallies", () {
+      var x = 0;
+      f() async {
+        try {
+          try {
+            return 42;
+          } finally {
+            x = await new Future.value(37);
+          }
+        } finally {
+          x += await new Future.value(37);
+        }
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(74));
+      });
+    });
 
     test("nested finallies 2", () {
       var x = 0;
@@ -1049,23 +1047,25 @@
       });
     });
 
-    // test("nested finallies 3", () {
-    //   var x = 0;
-    //   f() async {
-    //     label: try {
-    //       try {
-    //         break label;
-    //       } finally {
-    //         return await new Future.value(42);
-    //       }
-    //     } finally {
-    //       break label;
-    //     }
-    //     return 42;
-    //   }
-    //   return expect42(f());
-    // });
+    test("nested finallies 3", () {
+      var x = 0;
+      f() async {
+        label: try {
+          try {
+            break label;
+          } finally {
+            return await new Future.value(42);
+          }
+        } finally {
+          break label;
+        }
+        return 42;
+      }
+      return expect42(f());
+    });
 
+    // Expected: 'err'
+    // Actual: NullThrownError
     // test("nested finallies, throw", () {
     //   var x = 0;
     //   f() async {
@@ -1127,23 +1127,23 @@
       return expect42(f());
     });
 
-    // test("await in finally", () {
-    //   var x = 0;
-    //   f() async {
-    //     try {
-    //       return id(42);
-    //     } catch (e) {
-    //       throw null;
-    //     } finally {
-    //       x = await new Future.value(37);
-    //       if (id(42) == id(10)) return 10;
-    //     }
-    //   }
-    //   return f().then((v) {
-    //     expect(v, equals(42));
-    //     expect(x, equals(37));
-    //   });
-    // });
+    test("await in finally", () {
+      var x = 0;
+      f() async {
+        try {
+          return id(42);
+        } catch (e) {
+          throw null;
+        } finally {
+          x = await new Future.value(37);
+          if (id(42) == id(10)) return 10;
+        }
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
   });
 
   group("switch", () {
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index db67f27..3d1d017 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -22,8 +22,6 @@
 accessor_conflict_import_prefixed_test: RuntimeError
 accessor_conflict_import_test: RuntimeError
 assertion_test: RuntimeError
-async_break_in_finally_test: RuntimeError
-async_control_structures_test: RuntimeError
 async_star_cancel_and_throw_in_finally_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError
 async_star_regression_fisk_test: Timeout
@@ -35,8 +33,6 @@
 asyncstar_throw_in_catch_test: Timeout
 asyncstar_yield_test: Timeout
 asyncstar_yieldstar_test: Timeout
-await_exceptions_test: RuntimeError
-await_future_test: RuntimeError
 bad_constructor_test/05: CompileTimeError
 bad_raw_string_negative_test: Fail
 cha_deopt1_test: RuntimeError
@@ -353,8 +349,6 @@
 accessor_conflict_import_prefixed_test: RuntimeError
 accessor_conflict_import_test: RuntimeError
 assertion_test: RuntimeError
-async_break_in_finally_test: RuntimeError
-async_control_structures_test: RuntimeError
 async_star_cancel_and_throw_in_finally_test: RuntimeError
 async_star_cancel_while_paused_test: RuntimeError
 async_star_regression_fisk_test: Timeout
@@ -366,8 +360,6 @@
 asyncstar_throw_in_catch_test: Timeout
 asyncstar_yield_test: Timeout
 asyncstar_yieldstar_test: Timeout
-await_exceptions_test: RuntimeError
-await_future_test: RuntimeError
 bad_constructor_test/05: CompileTimeError
 bad_raw_string_negative_test: Fail
 cha_deopt1_test: RuntimeError