Version 2.8.0-dev.20.7

* Cherry-pick 05e43cff921c23cdf52558538ecf84d8091d3cdb to beta
* Cherry-pick 5ed1850933651b13cb52fc9319c2cbc599fc97d6 to beta
* Cherry-pick 795c0b1b64ce563e8924e0d0b7ed0bde98c1cef3 to beta
* Cherry-pick 7baa21d97a3d07c5837cdac79bf406f36b878279 to beta
* Cherry-pick 8df9c9408b14507e0e0b9007b093353ebff6d021 to beta
* Cherry-pick 12f09896dbfaa6576719b52aabf98cb5979a335d to beta
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d936ce..40ba119 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,15 +9,20 @@
 
 ### Language
 
-There are no new language features in this release. The only noteworthy change
-is a very minor breaking change in anticipation of the future support for null
-safety.
+There are no new language features in this release. There are only two
+minor breaking changes:
 
 *   **Breaking change** [#40675][]: Fixed an implementation bug where local
     variable inference would incorrectly use the promoted type of a type
     variable.
 
+*   **Breaking change** [#41362][]: Dart 2.0.0 made the clauses `implements
+    Function`, `extends Function`, or `with Function` have no effect (spec
+    section 19.6). We fixed an implementation bug that may be visible on some
+    rare scenarios.
+
 [#40675]: https://github.com/dart-lang/sdk/issues/40675
+[#41362]: https://github.com/dart-lang/sdk/issues/41362
 
 ### Core libraries
 
diff --git a/DEPS b/DEPS
index c8cbb91..40774ba 100644
--- a/DEPS
+++ b/DEPS
@@ -118,7 +118,7 @@
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "1.3.6",
   "protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
-  "pub_rev": "978cc9c4be7d8978348e56d4ae82be8257a59579",
+  "pub_rev": "3606265962da4248d34d352aa3d170aae4496a90",
   "pub_semver_tag": "v1.4.4",
   "quiver-dart_tag": "2.0.0+1",
   "resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
diff --git a/runtime/bin/dartdev_utils.cc b/runtime/bin/dartdev_utils.cc
index 88ac6f3..4708e1e 100644
--- a/runtime/bin/dartdev_utils.cc
+++ b/runtime/bin/dartdev_utils.cc
@@ -30,11 +30,12 @@
 
 bool DartDevUtils::TryResolveDartDevSnapshotPath(char** script_name) {
   // |dir_prefix| includes the last path seperator.
-  auto dir_prefix = EXEUtils::GetDirectoryPrefixFromExeName();
+  auto dir_prefix = std::unique_ptr<char, void (*)(void*)>(
+      EXEUtils::GetDirectoryPrefixFromExeName(), free);
 
   // First assume we're in dart-sdk/bin.
   char* snapshot_path =
-      Utils::SCreate("%ssnapshots/dartdev.dart.snapshot", dir_prefix.get());
+      Utils::SCreate("%s/snapshots/dartdev.dart.snapshot", dir_prefix.get());
   if (File::Exists(nullptr, snapshot_path)) {
     *script_name = snapshot_path;
     return true;
@@ -44,7 +45,7 @@
   // If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
   // directories. Try to use a snapshot from a previously built SDK.
   snapshot_path = Utils::SCreate(
-      "%sdart-sdk/bin/snapshots/dartdev.dart.snapshot", dir_prefix.get());
+      "%s/dart-sdk/bin/snapshots/dartdev.dart.snapshot", dir_prefix.get());
   if (File::Exists(nullptr, snapshot_path)) {
     *script_name = snapshot_path;
     return true;
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 39dec0c..f700d50 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -113,7 +113,8 @@
   }
 
   // |dir_prefix| includes the last path seperator.
-  auto dir_prefix = EXEUtils::GetDirectoryPrefixFromExeName();
+  auto dir_prefix = std::unique_ptr<char, void (*)(void*)>(
+      EXEUtils::GetDirectoryPrefixFromExeName(), free);
 
   if (target_abi_version != Options::kAbiVersionUnset) {
     kernel_service_dill_ = nullptr;
diff --git a/runtime/bin/exe_utils.cc b/runtime/bin/exe_utils.cc
index 091f890..81568ab 100644
--- a/runtime/bin/exe_utils.cc
+++ b/runtime/bin/exe_utils.cc
@@ -12,36 +12,7 @@
 namespace dart {
 namespace bin {
 
-// Returns the directory portion of a given path.
-//
-// If dir is NULL, the result must be freed by the caller. Otherwise, the
-// result is copied into dir.
-static char* GetDirectoryFromPath(const char* path, char* dir) {
-  const char* sep = File::PathSeparator();
-  const intptr_t sep_length = strlen(sep);
-  intptr_t path_len = strlen(path);
-
-  for (intptr_t i = path_len - 1; i >= 0; --i) {
-    const char* str = path + i;
-    if (strncmp(str, sep, sep_length) == 0
-#if defined(HOST_OS_WINDOWS)
-        // TODO(aam): GetExecutableName doesn't work reliably on Windows,
-        || *str == '/'
-#endif
-    ) {
-      if (dir != nullptr) {
-        strncpy(dir, path, i);
-        dir[i] = '\0';
-        return dir;
-      } else {
-        return Utils::StrNDup(path, i + 1);
-      }
-    }
-  }
-  return nullptr;
-}
-
-Utils::CStringUniquePtr EXEUtils::GetDirectoryPrefixFromExeName() {
+char* EXEUtils::GetDirectoryPrefixFromExeName() {
   const char* name = nullptr;
   const int kTargetSize = 4096;
   char target[kTargetSize];
@@ -56,32 +27,40 @@
     target_size = strlen(name);
   }
   Namespace* namespc = Namespace::Create(Namespace::Default());
-  if (File::GetType(namespc, name, false) == File::kIsLink) {
-    char dir_path[kTargetSize];
-    // cwd is currently wherever we launched from, so set the cwd to the
-    // directory of the symlink while we try and resolve it. If we don't
-    // do this, we won't be able to properly resolve relative paths.
-    auto initial_dir_path =
-        Utils::CreateCStringUniquePtr(Directory::CurrentNoScope());
-    // We might run into symlinks of symlinks, so make sure we follow the
-    // links all the way. See https://github.com/dart-lang/sdk/issues/41057 for
-    // an example where this happens with brew on MacOS.
-    do {
-      Directory::SetCurrent(namespc, GetDirectoryFromPath(name, dir_path));
-      // Resolve the link without creating Dart scope String.
-      name = File::LinkTarget(namespc, name, target, kTargetSize);
-      if (name == nullptr) {
-        return Utils::CreateCStringUniquePtr(strdup(""));
-      }
-    } while (File::GetType(namespc, name, false) == File::kIsLink);
-    target_size = strlen(name);
 
-    // Reset cwd to the original value.
-    Directory::SetCurrent(namespc, initial_dir_path.get());
+  // We might run into symlinks of symlinks, so make sure we follow the
+  // links all the way. See https://github.com/dart-lang/sdk/issues/41057 for
+  // an example where this happens with brew on MacOS.
+  bool followedSymlink = false;
+  while (File::GetType(namespc, name, false) == File::kIsLink) {
+    // Resolve the link without creating Dart scope String.
+    name = File::LinkTarget(namespc, name, target, kTargetSize);
+    if (name == NULL) {
+      return strdup("");
+    }
+    followedSymlink = true;
+  }
+  if (followedSymlink) {
+    target_size = strlen(name);
   }
   namespc->Release();
-  char* result = GetDirectoryFromPath(name, nullptr);
-  return Utils::CreateCStringUniquePtr(result == nullptr ? strdup("") : result);
+  const char* sep = File::PathSeparator();
+  const intptr_t sep_length = strlen(sep);
+
+  for (intptr_t i = target_size - 1; i >= 0; --i) {
+    const char* str = name + i;
+    if (strncmp(str, sep, sep_length) == 0
+#if defined(HOST_OS_WINDOWS)
+        // TODO(aam): GetExecutableName doesn't work reliably on Windows,
+        // the code below is a workaround for that (we would be using
+        // just single Platform::Separator instead of both slashes if it did).
+        || *str == '/'
+#endif
+    ) {
+      return Utils::StrNDup(name, i + 1);
+    }
+  }
+  return strdup("");
 }
 
 }  // namespace bin
diff --git a/runtime/bin/exe_utils.h b/runtime/bin/exe_utils.h
index 0c3eafb..42d27fe 100644
--- a/runtime/bin/exe_utils.h
+++ b/runtime/bin/exe_utils.h
@@ -10,7 +10,6 @@
 
 #include "include/dart_api.h"
 #include "platform/globals.h"
-#include "platform/utils.h"
 
 namespace dart {
 namespace bin {
@@ -18,7 +17,7 @@
 class EXEUtils {
  public:
   // Returns the path to the directory the current executable resides in.
-  static Utils::CStringUniquePtr GetDirectoryPrefixFromExeName();
+  static char* GetDirectoryPrefixFromExeName();
 
  private:
   DISALLOW_COPY_AND_ASSIGN(EXEUtils);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 3f8332f..dd815bc 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -15381,7 +15381,7 @@
 
 // WARNING: Do not edit - generated code.
 
-@Native("Event,InputEvent")
+@Native("Event,InputEvent,SubmitEvent")
 class Event extends Interceptor {
   // In JS, canBubble and cancelable are technically required parameters to
   // init*Event. In practice, though, if they aren't provided they simply
diff --git a/sdk/lib/js_util/js_util.dart b/sdk/lib/js_util/js_util.dart
index 9f2f4cb..a299a30 100644
--- a/sdk/lib/js_util/js_util.dart
+++ b/sdk/lib/js_util/js_util.dart
@@ -76,9 +76,13 @@
 callMethod(o, String method, List args) =>
     JS('Object|Null', '#[#].apply(#, #)', o, method, o, args);
 
-bool instanceof(o, Function type) => JS('bool', '# instanceof #', o, type);
+/// Check whether [o] is an instance of [type].
+///
+/// The value in [type] is expected to be a JS-interop object that
+/// represents a valid JavaScript constructor function.
+bool instanceof(o, Object type) => JS('bool', '# instanceof #', o, type);
 
-callConstructor(Function constr, List arguments) {
+callConstructor(Object constr, List arguments) {
   if (arguments == null) {
     return JS('Object', 'new #()', constr);
   }
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index c8d19df..17aa9d8 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -15399,7 +15399,7 @@
 
 // WARNING: Do not edit - generated code.
 
-@Native("Event,InputEvent")
+@Native("Event,InputEvent,SubmitEvent")
 class Event extends Interceptor {
   // In JS, canBubble and cancelable are technically required parameters to
   // init*Event. In practice, though, if they aren't provided they simply
diff --git a/sdk_nnbd/lib/js_util/js_util.dart b/sdk_nnbd/lib/js_util/js_util.dart
index 86fd582..605f6d6 100644
--- a/sdk_nnbd/lib/js_util/js_util.dart
+++ b/sdk_nnbd/lib/js_util/js_util.dart
@@ -76,10 +76,14 @@
 dynamic callMethod(Object o, String method, List<Object?> args) =>
     JS('Object|Null', '#[#].apply(#, #)', o, method, o, args);
 
-bool instanceof(Object? o, Function type) =>
+/// Check whether [o] is an instance of [type].
+///
+/// The value in [type] is expected to be a JS-interop object that
+/// represents a valid JavaScript constructor function.
+bool instanceof(Object? o, Object type) =>
     JS('bool', '# instanceof #', o, type);
 
-dynamic callConstructor(Function constr, List<Object?> arguments) {
+dynamic callConstructor(Object constr, List<Object?> arguments) {
   if (arguments == null) {
     return JS('Object', 'new #()', constr);
   }
diff --git a/tests/lib/js/instanceof_test.dart b/tests/lib/js/instanceof_test.dart
new file mode 100644
index 0000000..65bbd21
--- /dev/null
+++ b/tests/lib/js/instanceof_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, 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.
+
+@JS()
+library instanceof_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+import 'dart:js_util';
+
+@JS()
+external void eval(String code);
+
+@JS('Class')
+class Class {
+  external Class();
+  external Constructor get constructor;
+}
+
+@JS()
+class Constructor {}
+
+void main() {
+  eval("self.Class = function Class() {}");
+  var o = new Class();
+  var constructor = o.constructor;
+  Expect.isTrue(instanceof(o, constructor));
+}
diff --git a/tests/lib/lib_vm.status b/tests/lib/lib_vm.status
index c4207d9..92cc427 100644
--- a/tests/lib/lib_vm.status
+++ b/tests/lib/lib_vm.status
@@ -21,9 +21,7 @@
 async/future_or_only_in_async_test/00: MissingCompileTimeError
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow # Infrequent timeouts.
 html/*: SkipByDesign # dart:html not supported on VM.
-js/datetime_roundtrip_test: CompileTimeError
-js/null_test: CompileTimeError
-js/prototype_access_test: CompileTimeError
+js/*: SkipByDesign
 mirrors/deferred_type_test: CompileTimeError
 mirrors/generic_bounded_by_type_parameter_test/02: MissingCompileTimeError
 mirrors/generic_bounded_test/01: MissingCompileTimeError
diff --git a/tests/lib_2/js/instanceof_test.dart b/tests/lib_2/js/instanceof_test.dart
new file mode 100644
index 0000000..65bbd21
--- /dev/null
+++ b/tests/lib_2/js/instanceof_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2020, 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.
+
+@JS()
+library instanceof_test;
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+import 'dart:js_util';
+
+@JS()
+external void eval(String code);
+
+@JS('Class')
+class Class {
+  external Class();
+  external Constructor get constructor;
+}
+
+@JS()
+class Constructor {}
+
+void main() {
+  eval("self.Class = function Class() {}");
+  var o = new Class();
+  var constructor = o.constructor;
+  Expect.isTrue(instanceof(o, constructor));
+}
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 4fd19d7..78b9986 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -12,9 +12,7 @@
 async/future_or_only_in_async_test/00: MissingCompileTimeError
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow # Infrequent timeouts.
 html/*: SkipByDesign # dart:html not supported on VM.
-js/datetime_roundtrip_test: CompileTimeError
-js/null_test: CompileTimeError
-js/prototype_access_test: CompileTimeError
+js/*: SkipByDesign
 mirrors/deferred_type_test: CompileTimeError
 mirrors/generic_bounded_by_type_parameter_test/02: MissingCompileTimeError
 mirrors/generic_bounded_test/01: MissingCompileTimeError
diff --git a/tools/VERSION b/tools/VERSION
index b8c543b..ce32c71 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -34,6 +34,6 @@
 MINOR 8
 PATCH 0
 PRERELEASE 20
-PRERELEASE_PATCH 1
+PRERELEASE_PATCH 7
 ABI_VERSION 32
 OLDEST_SUPPORTED_ABI_VERSION 32
diff --git a/tools/apps/update_homebrew/lib/src/impl.dart b/tools/apps/update_homebrew/lib/src/impl.dart
index 938108b..2a07403 100644
--- a/tools/apps/update_homebrew/lib/src/impl.dart
+++ b/tools/apps/update_homebrew/lib/src/impl.dart
@@ -27,19 +27,28 @@
 
 Future<void> _updateFormula(String channel, File file, String version,
     Map<String, String> hashes) async {
+  var contents = await file.readAsString();
+
+  // Replace the version identifier. Formulas with stable and pre-release
+  // versions have multiple identifiers and only the right one should be
+  // updated.
+  var versionId = channel == 'stable'
+      ? RegExp(r'version \"\d+\.\d+.\d+\"')
+      : RegExp(r'version \"\d+\.\d+.\d+\-.+\"');
+  contents = contents.replaceAll(versionId, 'version "$version"');
+
   // Extract files and hashes that are stored in the formula in this format:
   //  url "<url base>/<channel>/release/<version>/sdk/<artifact>.zip"
   //  sha256 "<hash>"
   var filesAndHashes = RegExp(
-      'channels/$channel/release' +
-          r'/(\d[\w\d\-\.]*)/sdk/([\w\d\-\.]+)\"\n(\s+)sha256 \"[\da-f]+\"',
+      'channels/$channel/release'
+      r'/(\d[\w\d\-\.]*)/sdk/([\w\d\-\.]+)\"\n(\s+)sha256 \"[\da-f]+\"',
       multiLine: true);
-  var contents = await file.readAsString();
   contents = contents.replaceAllMapped(filesAndHashes, (m) {
     var currentVersion = m.group(1);
     if (currentVersion == version) {
       throw new ArgumentError(
-          "Channel $channel is already at version $version in homebrew.");
+          'Channel $channel is already at version $version in homebrew.');
     }
     var artifact = m.group(2);
     var indent = m.group(3);
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 3231d7f..2174db6 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -299,7 +299,7 @@
         'ApplicationCache':
         'ApplicationCache,DOMApplicationCache,OfflineResourceList',
         'Event':
-        'Event,InputEvent',
+        'Event,InputEvent,SubmitEvent', # Workaround for issue 40901.
         'HTMLTableCellElement':
         'HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement',
         'GainNode':