Version 2.12.0-24.0.dev

Merge commit 'd13eaddf97d60c706f8a8969a8998ab6b083f753' into 'dev'
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index ac8456c..7f6e20e 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -43,7 +43,7 @@
   /// If [newPath] identifies an existing file, that file is replaced.
   /// If [newPath] identifies an existing resource the operation might fail and
   /// an exception is thrown.
-  File renameSync(String newPath);
+  File renameSync(String /*!*/ newPath);
 
   /// Synchronously write the given [bytes] to the file. The new content will
   /// replace any existing content.
@@ -81,12 +81,12 @@
   ///
   /// However, regardless of whether [path] is relative or absolute, normalize
   /// it by removing path components of the form '.' or '..'.
-  String canonicalizePath(String path);
+  String canonicalizePath(String /*!*/ path);
 
   /// Return `true` if the [path] references a resource in this folder.
   ///
   /// The [path] must be absolute and normalized.
-  bool contains(String path);
+  bool contains(String /*!*/ path);
 
   @override
   Folder copyTo(Folder parentFolder);
@@ -96,19 +96,19 @@
 
   /// Return an existing child [Resource] with the given [relPath].
   /// Return a not existing [File] if no such child exist.
-  Resource getChild(String relPath);
+  Resource getChild(String /*!*/ relPath);
 
   /// Return a [File] representing a child [Resource] with the given
   /// [relPath].  This call does not check whether a file with the given name
   /// exists on the filesystem - client must call the [File]'s `exists` getter
   /// to determine whether the folder actually exists.
-  File getChildAssumingFile(String relPath);
+  File getChildAssumingFile(String /*!*/ relPath);
 
   /// Return a [Folder] representing a child [Resource] with the given
   /// [relPath].  This call does not check whether a folder with the given name
   /// exists on the filesystem--client must call the [Folder]'s `exists` getter
   /// to determine whether the folder actually exists.
-  Folder getChildAssumingFolder(String relPath);
+  Folder getChildAssumingFolder(String /*!*/ relPath);
 
   /// Return a list of existing direct children [Resource]s (folders and files)
   /// in this folder, in no particular order.
@@ -145,7 +145,7 @@
   /// Existing files and folders will be overwritten.
   ///
   /// Return the resource corresponding to this resource in the parent folder.
-  Resource copyTo(Folder parentFolder);
+  Resource copyTo(Folder /*!*/ parentFolder);
 
   /// Synchronously deletes this resource and its children.
   ///
@@ -156,7 +156,7 @@
   /// this folder.
   ///
   /// The [path] must be absolute and normalized.
-  bool isOrContains(String path);
+  bool isOrContains(String /*!*/ path);
 
   /// Return a resource that refers to the same resource as this resource, but
   /// whose path does not contain any symbolic links.
@@ -177,14 +177,14 @@
   /// The [path] must be absolute and normalized.
   ///
   /// A file may or may not exist at this location.
-  File getFile(String path);
+  File getFile(String /*!*/ path);
 
   /// Return a [Folder] that corresponds to the given [path].
   ///
   /// The [path] must be absolute and normalized.
   ///
   /// A folder may or may not exist at this location.
-  Folder getFolder(String path);
+  Folder getFolder(String /*!*/ path);
 
   /// Complete with a list of modification times for the given [sources].
   ///
@@ -195,7 +195,7 @@
   /// Return the [Resource] that corresponds to the given [path].
   ///
   /// The [path] must be absolute and normalized.
-  Resource getResource(String path);
+  Resource getResource(String /*!*/ path);
 
   /// Return the folder in which the plugin with the given [pluginId] can store
   /// state that will persist across sessions. The folder returned for a given
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index d852cb0..caaeae1 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -44,6 +44,7 @@
   /// This is a utility method for testing; paths passed in to other methods in
   /// this class are never converted automatically.
   String convertPath(String path) {
+    assert(path != null);
     if (pathContext.style == pathos.windows.style) {
       if (path.startsWith(pathos.posix.separator)) {
         path = r'C:' + path;
@@ -84,12 +85,14 @@
 
   @override
   File getFile(String path) {
+    assert(path != null);
     _ensureAbsoluteAndNormalized(path);
     return _MemoryFile(this, path);
   }
 
   @override
   Folder getFolder(String path) {
+    assert(path != null);
     _ensureAbsoluteAndNormalized(path);
     return _MemoryFolder(this, path);
   }
@@ -104,6 +107,7 @@
 
   @override
   Resource getResource(String path) {
+    assert(path != null);
     _ensureAbsoluteAndNormalized(path);
     return _pathToResource[path] ?? _MemoryFile(this, path);
   }
@@ -115,6 +119,7 @@
   }
 
   void modifyFile(String path, String content) {
+    assert(content != null);
     _checkFileAtPath(path);
     _pathToBytes[path] = utf8.encode(content) as Uint8List;
     _pathToTimestamp[path] = nextStamp++;
@@ -203,6 +208,7 @@
   }
 
   void _checkFileAtPath(String path) {
+    assert(path != null);
     // TODO(brianwilkerson) Consider throwing a FileSystemException rather than
     // an ArgumentError.
     _MemoryResource resource = _pathToResource[path];
@@ -216,6 +222,7 @@
   }
 
   void _checkFolderAtPath(String path) {
+    assert(path != null);
     // TODO(brianwilkerson) Consider throwing a FileSystemException rather than
     // an ArgumentError.
     _MemoryResource resource = _pathToResource[path];
@@ -228,6 +235,7 @@
   /// The file system abstraction supports only absolute and normalized paths.
   /// This method is used to validate any input paths to prevent errors later.
   void _ensureAbsoluteAndNormalized(String path) {
+    assert(path != null);
     if (!pathContext.isAbsolute(path)) {
       throw ArgumentError("Path must be absolute : $path");
     }
@@ -238,6 +246,7 @@
 
   /// Create a new [_MemoryFile] without any content.
   _MemoryFile _newFile(String path) {
+    assert(path != null);
     String folderPath = pathContext.dirname(path);
     _MemoryResource folder = _pathToResource[folderPath];
     if (folder == null) {
@@ -251,6 +260,7 @@
   }
 
   void _notifyWatchers(String path, ChangeType changeType) {
+    assert(path != null);
     _pathToWatchers.forEach((String watcherPath,
         List<StreamController<WatchEvent>> streamControllers) {
       if (watcherPath == path || pathContext.isWithin(watcherPath, path)) {
@@ -263,6 +273,7 @@
   }
 
   _MemoryFile _renameFileSync(_MemoryFile file, String newPath) {
+    assert(newPath != null);
     String path = file.path;
     if (newPath == path) {
       return file;
@@ -285,6 +296,7 @@
   }
 
   String _resolveLinks(String path) {
+    assert(path != null);
     var linkTarget = _pathToLinkedPath[path];
     if (linkTarget != null) {
       return linkTarget;
@@ -424,6 +436,7 @@
 
   @override
   File copyTo(Folder parentFolder) {
+    assert(parentFolder != null);
     parentFolder.create();
     File destination = parentFolder.getChildAssumingFile(shortName);
     destination.writeAsBytesSync(readAsBytesSync());
@@ -504,6 +517,7 @@
 
   @override
   String canonicalizePath(String relPath) {
+    assert(relPath != null);
     relPath = provider.pathContext.normalize(relPath);
     String childPath = provider.pathContext.join(path, relPath);
     childPath = provider.pathContext.normalize(childPath);
@@ -512,6 +526,7 @@
 
   @override
   bool contains(String path) {
+    assert(path != null);
     return provider.pathContext.isWithin(this.path, path);
   }
 
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 6e6b8e6..a030354 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -10,11 +10,11 @@
 
 import 'package:meta/meta.dart';
 
-/// Whether the program is running with weak null safety checking.
-bool get isWeakMode => const <Null>[] is List<Object>;
+/// Whether the program is running without sound null safety.
+bool get hasUnsoundNullSafety => const <Null>[] is List<Object>;
 
-/// Whether the program is running with strong null safety checking.
-bool get isStrongMode => !isWeakMode;
+/// Whether the program is running with sound null safety.
+bool get hasSoundNullSafety => !hasUnsoundNullSafety;
 
 /**
  * Expect is used for tests that do not want to make use of the
@@ -620,11 +620,11 @@
 
   /// Checks that [f] throws an appropriate error on a null argument.
   ///
-  /// In strong mode, this is expected to be a [TypeError] when casting the
-  /// `null` to some non-nullable type. In weak mode, that cast is ignored and
-  /// some later explicit validation should handle it and [ArgumentError].
+  /// With sound null safety, this is expected to be a [TypeError] when casting
+  /// the `null` to some non-nullable type. In weak mode, that cast is ignored
+  /// and some later explicit validation should handle it and [ArgumentError].
   static void throwsNullCheckError(void f()) {
-    if (isStrongMode) {
+    if (hasSoundNullSafety) {
       throwsTypeError(f);
     } else {
       throwsArgumentError(f);
diff --git a/pkg/expect/test/nnbd_mode_test.dart b/pkg/expect/test/nnbd_mode_test.dart
index 47fb624..35dd345 100644
--- a/pkg/expect/test/nnbd_mode_test.dart
+++ b/pkg/expect/test/nnbd_mode_test.dart
@@ -14,6 +14,6 @@
 }();
 
 void main() {
-  Expect.equals(strong, isStrongMode);
-  Expect.equals(!strong, isWeakMode);
+  Expect.equals(strong, hasSoundNullSafety);
+  Expect.equals(!strong, hasUnsoundNullSafety);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 366e68c..a4eebe8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -324,8 +324,8 @@
 
   /// List of built type aliased factory constructor invocations that require
   /// unaliasing.
-  final List<StaticInvocation> typeAliasedFactoryInvocations =
-      <StaticInvocation>[];
+  final List<TypeAliasedFactoryInvocationJudgment>
+      typeAliasedFactoryInvocations = [];
 
   /// Variables with metadata.  Their types need to be inferred late, for
   /// example, in [finishFunction].
@@ -1151,6 +1151,74 @@
     _resolveRedirectingFactoryTargets();
   }
 
+  /// Return an [Expression] resolving the argument invocation.
+  ///
+  /// The arguments specify the [StaticInvocation] whose `.target` is
+  /// [target], `.arguments` is [arguments], `.fileOffset` is [fileOffset],
+  /// and `.isConst` is [isConst].
+  Expression _resolveRedirectingFactoryTarget(
+      Procedure target, Arguments arguments, int fileOffset, bool isConst) {
+    Procedure initialTarget = target;
+    Expression replacementNode;
+
+    RedirectionTarget redirectionTarget =
+        getRedirectionTarget(initialTarget, this);
+    Member resolvedTarget = redirectionTarget?.target;
+
+    if (resolvedTarget == null) {
+      String name = constructorNameForDiagnostics(initialTarget.name.text,
+          className: initialTarget.enclosingClass.name);
+      // TODO(dmitryas): Report this error earlier.
+      replacementNode = buildProblem(
+          fasta.templateCyclicRedirectingFactoryConstructors
+              .withArguments(name),
+          initialTarget.fileOffset,
+          name.length);
+    } else if (resolvedTarget is Constructor &&
+        resolvedTarget.enclosingClass.isAbstract) {
+      replacementNode = evaluateArgumentsBefore(
+          forest.createArguments(noLocation, arguments.positional,
+              types: arguments.types, named: arguments.named),
+          buildAbstractClassInstantiationError(
+              fasta.templateAbstractRedirectedClassInstantiation
+                  .withArguments(resolvedTarget.enclosingClass.name),
+              resolvedTarget.enclosingClass.name,
+              initialTarget.fileOffset));
+    } else {
+      RedirectingFactoryBody redirectingFactoryBody =
+          getRedirectingFactoryBody(resolvedTarget);
+      if (redirectingFactoryBody != null) {
+        // If the redirection target is itself a redirecting factory, it means
+        // that it is unresolved.
+        assert(redirectingFactoryBody.isUnresolved);
+        String errorName = redirectingFactoryBody.unresolvedName;
+        replacementNode = buildProblem(
+            fasta.templateMethodNotFound.withArguments(errorName),
+            fileOffset,
+            noLength,
+            suppressMessage: true);
+      } else {
+        Substitution substitution = Substitution.fromPairs(
+            initialTarget.function.typeParameters, arguments.types);
+        arguments.types.clear();
+        arguments.types.length = redirectionTarget.typeArguments.length;
+        for (int i = 0; i < arguments.types.length; i++) {
+          arguments.types[i] =
+              substitution.substituteType(redirectionTarget.typeArguments[i]);
+        }
+
+        replacementNode = buildStaticInvocation(
+            resolvedTarget,
+            forest.createArguments(noLocation, arguments.positional,
+                types: arguments.types, named: arguments.named),
+            constness:
+                isConst ? Constness.explicitConst : Constness.explicitNew,
+            charOffset: fileOffset);
+      }
+    }
+    return replacementNode;
+  }
+
   void _resolveRedirectingFactoryTargets() {
     for (StaticInvocation invocation in redirectingFactoryInvocations) {
       // If the invocation was invalid, it or its parent has already been
@@ -1172,73 +1240,8 @@
         }
         if (parent == null) continue;
       }
-
-      Procedure initialTarget = invocation.target;
-      Expression replacementNode;
-
-      RedirectionTarget redirectionTarget =
-          getRedirectionTarget(initialTarget, this);
-      Member resolvedTarget = redirectionTarget?.target;
-
-      if (resolvedTarget == null) {
-        String name = constructorNameForDiagnostics(initialTarget.name.text,
-            className: initialTarget.enclosingClass.name);
-        // TODO(dmitryas): Report this error earlier.
-        replacementNode = buildProblem(
-            fasta.templateCyclicRedirectingFactoryConstructors
-                .withArguments(name),
-            initialTarget.fileOffset,
-            name.length);
-      } else if (resolvedTarget is Constructor &&
-          resolvedTarget.enclosingClass.isAbstract) {
-        replacementNode = evaluateArgumentsBefore(
-            forest.createArguments(noLocation, invocation.arguments.positional,
-                types: invocation.arguments.types,
-                named: invocation.arguments.named),
-            buildAbstractClassInstantiationError(
-                fasta.templateAbstractRedirectedClassInstantiation
-                    .withArguments(resolvedTarget.enclosingClass.name),
-                resolvedTarget.enclosingClass.name,
-                initialTarget.fileOffset));
-      } else {
-        RedirectingFactoryBody redirectingFactoryBody =
-            getRedirectingFactoryBody(resolvedTarget);
-        if (redirectingFactoryBody != null) {
-          // If the redirection target is itself a redirecting factory, it means
-          // that it is unresolved.
-          assert(redirectingFactoryBody.isUnresolved);
-          String errorName = redirectingFactoryBody.unresolvedName;
-          replacementNode = buildProblem(
-              fasta.templateMethodNotFound.withArguments(errorName),
-              invocation.fileOffset,
-              noLength,
-              suppressMessage: true);
-        } else {
-          Substitution substitution = Substitution.fromPairs(
-              initialTarget.function.typeParameters,
-              invocation.arguments.types);
-          invocation.arguments.types.clear();
-          invocation.arguments.types.length =
-              redirectionTarget.typeArguments.length;
-          for (int i = 0; i < invocation.arguments.types.length; i++) {
-            invocation.arguments.types[i] =
-                substitution.substituteType(redirectionTarget.typeArguments[i]);
-          }
-
-          replacementNode = buildStaticInvocation(
-              resolvedTarget,
-              forest.createArguments(
-                  noLocation, invocation.arguments.positional,
-                  types: invocation.arguments.types,
-                  named: invocation.arguments.named),
-              constness: invocation.isConst
-                  ? Constness.explicitConst
-                  : Constness.explicitNew,
-              charOffset: invocation.fileOffset);
-        }
-      }
-
-      invocation.replaceWith(replacementNode);
+      invocation.replaceWith(_resolveRedirectingFactoryTarget(invocation.target,
+          invocation.arguments, invocation.fileOffset, invocation.isConst));
     }
     redirectingFactoryInvocations.clear();
   }
@@ -1255,10 +1258,9 @@
       if (unaliasedType is InterfaceType) {
         invocationTypeArguments = unaliasedType.typeArguments;
       }
-      Arguments invocationArguments = new ArgumentsImpl(
-          invocation.arguments.positional,
-          types: invocationTypeArguments,
-          named: invocation.arguments.named);
+      Arguments invocationArguments = forest.createArguments(
+          noLocation, invocation.arguments.positional,
+          types: invocationTypeArguments, named: invocation.arguments.named);
       invocation.replaceWith(new ConstructorInvocation(
           invocation.target, invocationArguments,
           isConst: invocation.isConst));
@@ -1267,10 +1269,22 @@
   }
 
   void _unaliasTypeAliasedFactoryInvocations() {
-    for (StaticInvocation invocation in typeAliasedFactoryInvocations) {
-      // TODO(eernst): Should replace aliased factory invocations,
-      // such that back ends don't see instance creations on type aliases.
-      invocation.replaceWith(new NullLiteral());
+    for (TypeAliasedFactoryInvocationJudgment invocation
+        in typeAliasedFactoryInvocations) {
+      DartType unaliasedType = new TypedefType(
+              invocation.typeAliasBuilder.typedef,
+              Nullability.nonNullable,
+              invocation.arguments.types)
+          .unalias;
+      List<DartType> invocationTypeArguments = null;
+      if (unaliasedType is InterfaceType) {
+        invocationTypeArguments = unaliasedType.typeArguments;
+      }
+      Arguments invocationArguments = forest.createArguments(
+          noLocation, invocation.arguments.positional,
+          types: invocationTypeArguments, named: invocation.arguments.named);
+      invocation.replaceWith(_resolveRedirectingFactoryTarget(invocation.target,
+          invocationArguments, invocation.fileOffset, invocation.isConst));
     }
     typeAliasedFactoryInvocations.clear();
   }
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index 918b045..bb85a96 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -54,9 +54,9 @@
 //
 // You must check [IsConcreteNativeType] and [CheckSized] first to verify that
 // this type has a defined size.
-static size_t SizeOf(const AbstractType& type, Zone* zone) {
+static size_t SizeOf(Zone* zone, const AbstractType& type) {
   if (IsFfiTypeClassId(type.type_class_id())) {
-    return compiler::ffi::NativeType::FromAbstractType(type, zone)
+    return compiler::ffi::NativeType::FromAbstractType(zone, type)
         .SizeInBytes();
   } else {
     Class& struct_class = Class::Handle(type.type_class());
@@ -122,7 +122,7 @@
   // TODO(36370): Make representation consistent with kUnboxedFfiIntPtr.
   const size_t address =
       pointer.NativeAddress() + static_cast<intptr_t>(index.AsInt64Value()) *
-                                    SizeOf(pointer_type_arg, zone);
+                                    SizeOf(zone, pointer_type_arg);
   const Pointer& pointer_offset =
       Pointer::Handle(zone, Pointer::New(pointer_type_arg, address));
 
@@ -142,7 +142,7 @@
   GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
   CheckSized(type_arg);
 
-  return Integer::New(SizeOf(type_arg, zone));
+  return Integer::New(SizeOf(zone, type_arg));
 }
 
 // Static invocations to this method are translated directly in streaming FGB.
diff --git a/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart b/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
index d80e4e1..99a8bf1 100644
--- a/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_stack_limit_rpc_test.dart
@@ -2,6 +2,8 @@
 // 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=--causal-async-stacks --no-lazy-async-stacks
+
 import 'dart:async';
 import 'dart:developer';
 
diff --git a/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
index 4c2f286..5248ebc 100644
--- a/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_stack_limit_rpc_test.dart
@@ -2,6 +2,8 @@
 // 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=--causal-async-stacks --no-lazy-async-stacks
+
 import 'dart:async';
 import 'dart:developer';
 
diff --git a/runtime/tests/vm/dart/error_messages_in_null_checks_test.dart b/runtime/tests/vm/dart/error_messages_in_null_checks_test.dart
index 2a64885..30e08ef 100644
--- a/runtime/tests/vm/dart/error_messages_in_null_checks_test.dart
+++ b/runtime/tests/vm/dart/error_messages_in_null_checks_test.dart
@@ -89,7 +89,7 @@
 
   Expect.throws(
       () => 9.81 - doubleNull,
-      (e) => isWeakMode
+      (e) => hasUnsoundNullSafety
           ? (e is NoSuchMethodError &&
               // If '-' is specialized.
               (e.toString().startsWith(
diff --git a/runtime/tests/vm/dart/null_checks_with_dwarf_stack_traces_test.dart b/runtime/tests/vm/dart/null_checks_with_dwarf_stack_traces_test.dart
index b508ea8..7a87925 100644
--- a/runtime/tests/vm/dart/null_checks_with_dwarf_stack_traces_test.dart
+++ b/runtime/tests/vm/dart/null_checks_with_dwarf_stack_traces_test.dart
@@ -52,8 +52,10 @@
 
   Expect.throws(() => doubleNull + 2.17, (e) => e is NoSuchMethodError);
 
-  Expect.throws(() => 9.81 - doubleNull,
-      (e) => isWeakMode ? (e is NoSuchMethodError) : (e is TypeError));
+  Expect.throws(
+      () => 9.81 - doubleNull,
+      (e) =>
+          hasUnsoundNullSafety ? (e is NoSuchMethodError) : (e is TypeError));
 
   Expect.throws(() => intNull * 7, (e) => e is NoSuchMethodError);
 }
diff --git a/runtime/tests/vm/dart/transferable_throws_test.dart b/runtime/tests/vm/dart/transferable_throws_test.dart
index c2a35d6..2ad3605 100644
--- a/runtime/tests/vm/dart/transferable_throws_test.dart
+++ b/runtime/tests/vm/dart/transferable_throws_test.dart
@@ -107,7 +107,7 @@
   throwsIfCummulativeListIsTooLargeOn32bitPlatform();
 
   dynamic myNull;
-  if (isWeakMode) {
+  if (hasUnsoundNullSafety) {
     Expect.throwsArgumentError(() => TransferableTypedData.fromList(myNull));
     Expect.throwsArgumentError(() => TransferableTypedData.fromList([myNull]));
     Expect.throwsArgumentError(
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 779eadd..4310ef2 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1671,19 +1671,27 @@
   LeaveStubFrame();
 }
 
-void Assembler::CallCFunction(Register reg) {
+void Assembler::CallCFunction(Register reg, bool restore_rsp) {
   // Reserve shadow space for outgoing arguments.
   if (CallingConventions::kShadowSpaceBytes != 0) {
     subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
   }
   call(reg);
+  // Restore stack.
+  if (restore_rsp && CallingConventions::kShadowSpaceBytes != 0) {
+    addq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
+  }
 }
-void Assembler::CallCFunction(Address address) {
+void Assembler::CallCFunction(Address address, bool restore_rsp) {
   // Reserve shadow space for outgoing arguments.
   if (CallingConventions::kShadowSpaceBytes != 0) {
     subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
   }
   call(address);
+  // Restore stack.
+  if (restore_rsp && CallingConventions::kShadowSpaceBytes != 0) {
+    addq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
+  }
 }
 
 void Assembler::CallRuntime(const RuntimeEntry& entry,
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 19bf03f..f6576ff 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -829,9 +829,9 @@
   void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
 
   // Call runtime function. Reserves shadow space on the stack before calling
-  // if platform ABI requires that. Does not restore RSP after the call itself.
-  void CallCFunction(Register reg);
-  void CallCFunction(Address address);
+  // if platform ABI requires that.
+  void CallCFunction(Register reg, bool restore_rsp = false);
+  void CallCFunction(Address address, bool restore_rsp = false);
 
   void ExtractClassIdFromTags(Register result, Register tags);
   void ExtractInstanceSizeFromTags(Register result, Register tags);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 1c0f9db..e943f75 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -2748,8 +2748,8 @@
   const intptr_t dst_container_size = dst_container_type.SizeInBytes();
 
   // This function does not know how to do larger mem copy moves yet.
-  ASSERT(src_payload_type.IsFundamental());
-  ASSERT(dst_payload_type.IsFundamental());
+  ASSERT(src_payload_type.IsPrimitive());
+  ASSERT(dst_payload_type.IsPrimitive());
 
   // This function does not deal with sign conversions yet.
   ASSERT(src_payload_type.IsSigned() == dst_payload_type.IsSigned());
@@ -2773,9 +2773,9 @@
       // The upper bits of the source are already properly sign or zero
       // extended, so just copy the required amount of bits.
       return EmitNativeMove(destination.WithOtherNativeType(
-                                dst_container_type, dst_container_type, zone_),
+                                zone_, dst_container_type, dst_container_type),
                             source.WithOtherNativeType(
-                                dst_container_type, dst_container_type, zone_),
+                                zone_, dst_container_type, dst_container_type),
                             temp);
     }
     if (src_payload_size >= dst_payload_size &&
@@ -2783,9 +2783,9 @@
       // The upper bits of the source are not properly sign or zero extended
       // to be copied to the target, so regard the source as smaller.
       return EmitNativeMove(
-          destination.WithOtherNativeType(dst_container_type,
-                                          dst_container_type, zone_),
-          source.WithOtherNativeType(dst_payload_type, dst_payload_type, zone_),
+          destination.WithOtherNativeType(zone_, dst_container_type,
+                                          dst_container_type),
+          source.WithOtherNativeType(zone_, dst_payload_type, dst_payload_type),
           temp);
     }
     UNREACHABLE();
@@ -2800,8 +2800,8 @@
       !destination.IsFpuRegisters()) {
     // TODO(40209): If this is stack to stack, we could use FpuTMP.
     // Test the impact on code size and speed.
-    EmitNativeMove(destination.Split(0, zone_), source.Split(0, zone_), temp);
-    EmitNativeMove(destination.Split(1, zone_), source.Split(1, zone_), temp);
+    EmitNativeMove(destination.Split(zone_, 0), source.Split(zone_, 0), temp);
+    EmitNativeMove(destination.Split(zone_, 1), source.Split(zone_, 1), temp);
     return;
   }
 
@@ -2829,7 +2829,7 @@
   if (sign_or_zero_extend && destination.IsStack()) {
     ASSERT(source.IsRegisters());
     const auto& intermediate =
-        source.WithOtherNativeType(dst_payload_type, dst_container_type, zone_);
+        source.WithOtherNativeType(zone_, dst_payload_type, dst_container_type);
     EmitNativeMove(intermediate, source, temp);
     EmitNativeMove(destination, intermediate, temp);
     return;
@@ -2840,7 +2840,7 @@
   if (sign_or_zero_extend && source.IsStack()) {
     ASSERT(destination.IsRegisters());
     const auto& intermediate = destination.WithOtherNativeType(
-        src_payload_type, src_container_type, zone_);
+        zone_, src_payload_type, src_container_type);
     EmitNativeMove(intermediate, source, temp);
     EmitNativeMove(destination, intermediate, temp);
     return;
@@ -2875,12 +2875,12 @@
   if (src_loc.IsPairLocation()) {
     for (intptr_t i : {0, 1}) {
       const auto& src_split = compiler::ffi::NativeLocation::FromPairLocation(
-          src_loc, src_type, i, zone_);
-      EmitNativeMove(dst.Split(i, zone_), src_split, temp);
+          zone_, src_loc, src_type, i);
+      EmitNativeMove(dst.Split(zone_, i), src_split, temp);
     }
   } else {
     const auto& src =
-        compiler::ffi::NativeLocation::FromLocation(src_loc, src_type, zone_);
+        compiler::ffi::NativeLocation::FromLocation(zone_, src_loc, src_type);
     EmitNativeMove(dst, src, temp);
   }
 }
@@ -2895,12 +2895,12 @@
   if (dst_loc.IsPairLocation()) {
     for (intptr_t i : {0, 1}) {
       const auto& dest_split = compiler::ffi::NativeLocation::FromPairLocation(
-          dst_loc, dst_type, i, zone_);
-      EmitNativeMove(dest_split, src.Split(i, zone_), temp);
+          zone_, dst_loc, dst_type, i);
+      EmitNativeMove(dest_split, src.Split(zone_, i), temp);
     }
   } else {
     const auto& dest =
-        compiler::ffi::NativeLocation::FromLocation(dst_loc, dst_type, zone_);
+        compiler::ffi::NativeLocation::FromLocation(zone_, dst_loc, dst_type);
     EmitNativeMove(dest, src, temp);
   }
 }
@@ -2935,20 +2935,20 @@
     if (src.IsPairLocation()) {
       for (intptr_t i : {0, 1}) {
         const Representation src_type_split =
-            compiler::ffi::NativeType::FromUnboxedRepresentation(src_type,
-                                                                 zone_)
-                .Split(i, zone_)
+            compiler::ffi::NativeType::FromUnboxedRepresentation(zone_,
+                                                                 src_type)
+                .Split(zone_, i)
                 .AsRepresentation();
         const auto& intermediate_native =
-            compiler::ffi::NativeLocation::FromLocation(intermediate,
-                                                        src_type_split, zone_);
+            compiler::ffi::NativeLocation::FromLocation(zone_, intermediate,
+                                                        src_type_split);
         EmitMove(intermediate, src.AsPairLocation()->At(i), temp);
-        EmitNativeMove(dst.Split(i, zone_), intermediate_native, temp);
+        EmitNativeMove(dst.Split(zone_, i), intermediate_native, temp);
       }
     } else {
       const auto& intermediate_native =
-          compiler::ffi::NativeLocation::FromLocation(intermediate, src_type,
-                                                      zone_);
+          compiler::ffi::NativeLocation::FromLocation(zone_, intermediate,
+                                                      src_type);
       EmitMove(intermediate, src, temp);
       EmitNativeMove(dst, intermediate_native, temp);
     }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index d1de64a..66f966d 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -1446,8 +1446,8 @@
   ASSERT(src_container_type.IsFloat() == dst_container_type.IsFloat());
   ASSERT(src_container_type.IsInt() == dst_container_type.IsInt());
   ASSERT(src_payload_type.IsSigned() == dst_payload_type.IsSigned());
-  ASSERT(src_payload_type.IsFundamental());
-  ASSERT(dst_payload_type.IsFundamental());
+  ASSERT(src_payload_type.IsPrimitive());
+  ASSERT(dst_payload_type.IsPrimitive());
   const intptr_t src_size = src_payload_type.SizeInBytes();
   const intptr_t dst_size = dst_payload_type.SizeInBytes();
   const bool sign_or_zero_extend = dst_size > src_size;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 4ed5b4a..14cb38c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -1393,8 +1393,8 @@
   ASSERT(src_type.IsFloat() == dst_type.IsFloat());
   ASSERT(src_type.IsInt() == dst_type.IsInt());
   ASSERT(src_type.IsSigned() == dst_type.IsSigned());
-  ASSERT(src_type.IsFundamental());
-  ASSERT(dst_type.IsFundamental());
+  ASSERT(src_type.IsPrimitive());
+  ASSERT(dst_type.IsPrimitive());
   const intptr_t src_size = src_type.SizeInBytes();
   const intptr_t dst_size = dst_type.SizeInBytes();
   const bool sign_or_zero_extend = dst_size > src_size;
@@ -1420,7 +1420,7 @@
             UNIMPLEMENTED();
         }
       } else {
-        switch (src_type.AsFundamental().representation()) {
+        switch (src_type.AsPrimitive().representation()) {
           case compiler::ffi::kInt8:  // Sign extend operand.
             __ sxtb(dst_reg, src_reg);
             return;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 6b96aff..83f47d6 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -1302,8 +1302,8 @@
   ASSERT(src_type.IsFloat() == dst_type.IsFloat());
   ASSERT(src_type.IsInt() == dst_type.IsInt());
   ASSERT(src_type.IsSigned() == dst_type.IsSigned());
-  ASSERT(src_type.IsFundamental());
-  ASSERT(dst_type.IsFundamental());
+  ASSERT(src_type.IsPrimitive());
+  ASSERT(dst_type.IsPrimitive());
   const intptr_t src_size = src_type.SizeInBytes();
   const intptr_t dst_size = dst_type.SizeInBytes();
   const bool sign_or_zero_extend = dst_size > src_size;
@@ -1322,7 +1322,7 @@
         ASSERT(dst_size == 4);
         __ movl(dst_reg, src_reg);
       } else {
-        switch (src_type.AsFundamental().representation()) {
+        switch (src_type.AsPrimitive().representation()) {
           case compiler::ffi::kInt8:  // Sign extend operand.
             __ movsxb(dst_reg, ByteRegisterOf(src_reg));
             return;
@@ -1410,7 +1410,7 @@
         ASSERT(dst_size == 4);
         __ movl(dst_reg, src_addr);
       } else {
-        switch (src_type.AsFundamental().representation()) {
+        switch (src_type.AsPrimitive().representation()) {
           case compiler::ffi::kInt8:  // Sign extend operand.
             __ movsxb(dst_reg, src_addr);
             return;
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 72a326f..41e5961 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -1354,8 +1354,8 @@
   ASSERT(src_type.IsFloat() == dst_type.IsFloat());
   ASSERT(src_type.IsInt() == dst_type.IsInt());
   ASSERT(src_type.IsSigned() == dst_type.IsSigned());
-  ASSERT(src_type.IsFundamental());
-  ASSERT(dst_type.IsFundamental());
+  ASSERT(src_type.IsPrimitive());
+  ASSERT(dst_type.IsPrimitive());
   const intptr_t src_size = src_type.SizeInBytes();
   const intptr_t dst_size = dst_type.SizeInBytes();
   const bool sign_or_zero_extend = dst_size > src_size;
@@ -1381,7 +1381,7 @@
             UNIMPLEMENTED();
         }
       } else {
-        switch (src_type.AsFundamental().representation()) {
+        switch (src_type.AsPrimitive().representation()) {
           case compiler::ffi::kInt8:  // Sign extend operand.
             __ movsxb(dst_reg, src_reg);
             return;
@@ -1479,7 +1479,7 @@
             UNIMPLEMENTED();
         }
       } else {
-        switch (src_type.AsFundamental().representation()) {
+        switch (src_type.AsPrimitive().representation()) {
           case compiler::ffi::kInt8:  // Sign extend operand.
             __ movsxb(dst_reg, src_addr);
             return;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index fafae7a..fa55d52 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -4509,10 +4509,10 @@
   // for the two frame pointers and two return addresses of the entry frame.
   constexpr intptr_t kEntryFramePadding = 4;
   compiler::ffi::FrameRebase rebase(
+      compiler->zone(),
       /*old_base=*/SPREG, /*new_base=*/FPREG,
       (-kExitLinkSlotFromEntryFp + kEntryFramePadding) *
-          compiler::target::kWordSize,
-      compiler->zone());
+          compiler::target::kWordSize);
   const auto& src =
       rebase.Rebase(marshaller_.NativeLocationOfNativeParameter(index_));
   NoTemporaryAllocator no_temp;
@@ -6198,8 +6198,9 @@
   const Register saved_fp = locs()->temp(0).reg();
   const Register temp = locs()->temp(1).reg();
 
-  compiler::ffi::FrameRebase rebase(/*old_base=*/FPREG, /*new_base=*/saved_fp,
-                                    /*stack_delta=*/0, zone_);
+  compiler::ffi::FrameRebase rebase(zone_, /*old_base=*/FPREG,
+                                    /*new_base=*/saved_fp,
+                                    /*stack_delta=*/0);
   for (intptr_t i = 0, n = NativeArgCount(); i < n; ++i) {
     const Location origin = rebase.Rebase(locs()->in(i));
     const Representation origin_rep = RequiredInputRepresentation(i);
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index cdc4f79..50b1287 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -1082,7 +1082,7 @@
     __ TransitionGeneratedToNative(target_address, FPREG, TMP,
                                    /*enter_safepoint=*/true);
 
-    __ CallCFunction(target_address);
+    __ CallCFunction(target_address, /*restore_rsp=*/true);
 
     // Update information in the thread object and leave the safepoint.
     __ TransitionNativeToGenerated(/*leave_safepoint=*/true);
diff --git a/runtime/vm/compiler/ffi/frame_rebase.h b/runtime/vm/compiler/ffi/frame_rebase.h
index ba58a5c..618d33f 100644
--- a/runtime/vm/compiler/ffi/frame_rebase.h
+++ b/runtime/vm/compiler/ffi/frame_rebase.h
@@ -31,24 +31,24 @@
 // This class can be used to rebase both Locations and NativeLocations.
 class FrameRebase : public ValueObject {
  public:
-  FrameRebase(const Register old_base,
+  FrameRebase(Zone* zone,
+              const Register old_base,
               const Register new_base,
-              intptr_t stack_delta_in_bytes,
-              Zone* zone)
-      : old_base_(old_base),
+              intptr_t stack_delta_in_bytes)
+      : zone_(zone),
+        old_base_(old_base),
         new_base_(new_base),
-        stack_delta_in_bytes_(stack_delta_in_bytes),
-        zone_(zone) {}
+        stack_delta_in_bytes_(stack_delta_in_bytes) {}
 
   const NativeLocation& Rebase(const NativeLocation& loc) const;
 
   Location Rebase(const Location loc) const;
 
  private:
+  Zone* zone_;
   const Register old_base_;
   const Register new_base_;
   const intptr_t stack_delta_in_bytes_;
-  Zone* zone_;
 };
 
 }  // namespace ffi
diff --git a/runtime/vm/compiler/ffi/marshaller.cc b/runtime/vm/compiler/ffi/marshaller.cc
index 09dd56d..c095e9e 100644
--- a/runtime/vm/compiler/ffi/marshaller.cc
+++ b/runtime/vm/compiler/ffi/marshaller.cc
@@ -78,8 +78,8 @@
 class CallbackArgumentTranslator : public ValueObject {
  public:
   static NativeLocations& TranslateArgumentLocations(
-      const NativeLocations& arg_locs,
-      Zone* zone) {
+      Zone* zone,
+      const NativeLocations& arg_locs) {
     auto& pushed_locs = *(new NativeLocations(arg_locs.length()));
 
     CallbackArgumentTranslator translator;
@@ -122,10 +122,10 @@
         stack_delta += StubCodeCompiler::kNativeCallbackTrampolineStackDelta;
       }
       FrameRebase rebase(
+          zone,
           /*old_base=*/SPREG, /*new_base=*/SPREG,
           /*stack_delta=*/(argument_slots_required_ + stack_delta) *
-              compiler::target::kWordSize,
-          zone);
+              compiler::target::kWordSize);
       return rebase.Rebase(arg);
     }
 
@@ -153,8 +153,8 @@
                                        const Function& dart_signature)
     : BaseMarshaller(zone, dart_signature),
       callback_locs_(
-          CallbackArgumentTranslator::TranslateArgumentLocations(arg_locs_,
-                                                                 zone_)) {}
+          CallbackArgumentTranslator::TranslateArgumentLocations(zone_,
+                                                                 arg_locs_)) {}
 
 }  // namespace ffi
 
diff --git a/runtime/vm/compiler/ffi/native_calling_convention.cc b/runtime/vm/compiler/ffi/native_calling_convention.cc
index 47f6adc..84081aa 100644
--- a/runtime/vm/compiler/ffi/native_calling_convention.cc
+++ b/runtime/vm/compiler/ffi/native_calling_convention.cc
@@ -31,14 +31,14 @@
 }
 
 // In Soft FP, floats are treated as 4 byte ints, and doubles as 8 byte ints.
-static const NativeType& ConvertIfSoftFp(const NativeType& rep, Zone* zone) {
+static const NativeType& ConvertIfSoftFp(Zone* zone, const NativeType& rep) {
   if (SoftFpAbi() && rep.IsFloat()) {
     ASSERT(rep.IsFloat());
     if (rep.SizeInBytes() == 4) {
-      return *new (zone) NativeFundamentalType(kInt32);
+      return *new (zone) NativePrimitiveType(kInt32);
     }
     if (rep.SizeInBytes() == 8) {
-      return *new (zone) NativeFundamentalType(kInt64);
+      return *new (zone) NativePrimitiveType(kInt64);
     }
   }
   return rep;
@@ -46,25 +46,25 @@
 
 // Representations of the arguments to a C signature function.
 static ZoneGrowableArray<const NativeType*>& ArgumentRepresentations(
-    const Function& signature,
-    Zone* zone) {
+    Zone* zone,
+    const Function& signature) {
   const intptr_t num_arguments =
       signature.num_fixed_parameters() - kNativeParamsStartAt;
   auto& result = *new ZoneGrowableArray<const NativeType*>(zone, num_arguments);
   for (intptr_t i = 0; i < num_arguments; i++) {
     AbstractType& arg_type = AbstractType::Handle(
         zone, signature.ParameterTypeAt(i + kNativeParamsStartAt));
-    const auto& rep = NativeType::FromAbstractType(arg_type, zone);
+    const auto& rep = NativeType::FromAbstractType(zone, arg_type);
     result.Add(&rep);
   }
   return result;
 }
 
 // Representation of the result of a C signature function.
-static NativeType& ResultRepresentation(const Function& signature, Zone* zone) {
+static NativeType& ResultRepresentation(Zone* zone, const Function& signature) {
   AbstractType& result_type =
       AbstractType::Handle(zone, signature.result_type());
-  return NativeType::FromAbstractType(result_type, zone);
+  return NativeType::FromAbstractType(zone, result_type);
 }
 
 // Represents the state of a stack frame going into a call, between allocations
@@ -74,7 +74,7 @@
   explicit ArgumentAllocator(Zone* zone) : zone_(zone) {}
 
   const NativeLocation& AllocateArgument(const NativeType& payload_type) {
-    const auto& payload_type_converted = ConvertIfSoftFp(payload_type, zone_);
+    const auto& payload_type_converted = ConvertIfSoftFp(zone_, payload_type);
     if (payload_type_converted.IsFloat()) {
       const auto kind = FpuRegKind(payload_type);
       const intptr_t reg_index = FirstFreeFpuRegisterIndex(kind);
@@ -224,8 +224,8 @@
 
 // Location for the arguments of a C signature function.
 static NativeLocations& ArgumentLocations(
-    const ZoneGrowableArray<const NativeType*>& arg_reps,
-    Zone* zone) {
+    Zone* zone,
+    const ZoneGrowableArray<const NativeType*>& arg_reps) {
   intptr_t num_arguments = arg_reps.length();
   auto& result = *new NativeLocations(zone, num_arguments);
 
@@ -239,9 +239,9 @@
 }
 
 // Location for the result of a C signature function.
-static NativeLocation& ResultLocation(const NativeType& payload_type,
-                                      Zone* zone) {
-  const auto& payload_type_converted = ConvertIfSoftFp(payload_type, zone);
+static NativeLocation& ResultLocation(Zone* zone,
+                                      const NativeType& payload_type) {
+  const auto& payload_type_converted = ConvertIfSoftFp(zone, payload_type);
   const auto& container_type =
       CallingConventions::kReturnRegisterExtension == kExtendedTo4
           ? payload_type_converted.WidenTo4Bytes(zone)
@@ -267,10 +267,11 @@
                                                  const Function& c_signature)
     : zone_(ASSERT_NOTNULL(zone)),
       c_signature_(c_signature),
-      arg_locs_(ArgumentLocations(ArgumentRepresentations(c_signature_, zone_),
-                                  zone_)),
+      arg_locs_(
+          ArgumentLocations(zone_,
+                            ArgumentRepresentations(zone_, c_signature_))),
       result_loc_(
-          ResultLocation(ResultRepresentation(c_signature_, zone_), zone_)) {}
+          ResultLocation(zone_, ResultRepresentation(zone_, c_signature_))) {}
 
 intptr_t NativeCallingConvention::num_args() const {
   ASSERT(c_signature_.NumOptionalParameters() == 0);
diff --git a/runtime/vm/compiler/ffi/native_location.cc b/runtime/vm/compiler/ffi/native_location.cc
index bbc762e..f954e9f 100644
--- a/runtime/vm/compiler/ffi/native_location.cc
+++ b/runtime/vm/compiler/ffi/native_location.cc
@@ -29,14 +29,14 @@
   return false;
 }
 
-NativeLocation& NativeLocation::FromLocation(Location loc,
-                                             Representation rep,
-                                             Zone* zone) {
+NativeLocation& NativeLocation::FromLocation(Zone* zone,
+                                             Location loc,
+                                             Representation rep) {
   // TODO(36730): We could possibly consume a pair location as struct.
   ASSERT(LocationCanBeExpressed(loc, rep));
 
   const NativeType& native_rep =
-      NativeType::FromUnboxedRepresentation(rep, zone);
+      NativeType::FromUnboxedRepresentation(zone, rep);
 
   switch (loc.kind()) {
     case Location::Kind::kRegister:
@@ -61,18 +61,18 @@
 }
 
 // TODO(36730): Remove when being able to consume as struct.
-NativeLocation& NativeLocation::FromPairLocation(Location pair_loc,
+NativeLocation& NativeLocation::FromPairLocation(Zone* zone,
+                                                 Location pair_loc,
                                                  Representation pair_rep,
-                                                 intptr_t index,
-                                                 Zone* zone) {
+                                                 intptr_t index) {
   ASSERT(pair_loc.IsPairLocation());
   ASSERT(index == 0 || index == 1);
   const Representation rep =
-      NativeType::FromUnboxedRepresentation(pair_rep, zone)
-          .Split(index, zone)
+      NativeType::FromUnboxedRepresentation(zone, pair_rep)
+          .Split(zone, index)
           .AsRepresentation();
   const Location loc = pair_loc.AsPairLocation()->At(index);
-  return FromLocation(loc, rep, zone);
+  return FromLocation(zone, loc, rep);
 }
 
 const NativeRegistersLocation& NativeLocation::AsRegisters() const {
@@ -117,36 +117,36 @@
     }
   } else {
     ASSERT(payload_type().IsFloat());
-    if (payload_type().AsFundamental().representation() == kFloat) {
+    if (payload_type().AsPrimitive().representation() == kFloat) {
       return Location::StackSlot(offset_in_words(), base_register_);
     } else {
-      ASSERT(payload_type().AsFundamental().representation() == kDouble);
+      ASSERT(payload_type().AsPrimitive().representation() == kDouble);
       return Location::DoubleStackSlot(offset_in_words(), base_register_);
     }
   }
   UNREACHABLE();
 }
-NativeRegistersLocation& NativeRegistersLocation::Split(intptr_t index,
-                                                        Zone* zone) const {
+NativeRegistersLocation& NativeRegistersLocation::Split(Zone* zone,
+                                                        intptr_t index) const {
   ASSERT(num_regs() == 2);
   return *new (zone) NativeRegistersLocation(
-      payload_type().Split(index, zone), container_type().Split(index, zone),
+      payload_type().Split(zone, index), container_type().Split(zone, index),
       reg_at(index));
 }
 
-NativeStackLocation& NativeStackLocation::Split(intptr_t index,
-                                                Zone* zone) const {
+NativeStackLocation& NativeStackLocation::Split(Zone* zone,
+                                                intptr_t index) const {
   ASSERT(index == 0 || index == 1);
   const intptr_t size = payload_type().SizeInBytes();
 
   return *new (zone) NativeStackLocation(
-      payload_type().Split(index, zone), container_type().Split(index, zone),
+      payload_type().Split(zone, index), container_type().Split(zone, index),
       base_register_, offset_in_bytes_ + size / 2 * index);
 }
 
 NativeLocation& NativeLocation::WidenTo4Bytes(Zone* zone) const {
-  return WithOtherNativeType(payload_type().WidenTo4Bytes(zone),
-                             container_type().WidenTo4Bytes(zone), zone);
+  return WithOtherNativeType(zone, payload_type().WidenTo4Bytes(zone),
+                             container_type().WidenTo4Bytes(zone));
 }
 
 #if defined(TARGET_ARCH_ARM)
diff --git a/runtime/vm/compiler/ffi/native_location.h b/runtime/vm/compiler/ffi/native_location.h
index fefee76..78caa24 100644
--- a/runtime/vm/compiler/ffi/native_location.h
+++ b/runtime/vm/compiler/ffi/native_location.h
@@ -54,13 +54,13 @@
 class NativeLocation : public ZoneAllocated {
  public:
   static bool LocationCanBeExpressed(Location loc, Representation rep);
-  static NativeLocation& FromLocation(Location loc,
-                                      Representation rep,
-                                      Zone* zone);
-  static NativeLocation& FromPairLocation(Location loc,
+  static NativeLocation& FromLocation(Zone* zone,
+                                      Location loc,
+                                      Representation rep);
+  static NativeLocation& FromPairLocation(Zone* zone,
+                                          Location loc,
                                           Representation rep,
-                                          intptr_t index,
-                                          Zone* zone);
+                                          intptr_t index);
 
   // The type of the data at this location.
   const NativeType& payload_type() const { return payload_type_; }
@@ -74,9 +74,9 @@
   const NativeType& container_type() const { return container_type_; }
 
   virtual NativeLocation& WithOtherNativeType(
+      Zone* zone,
       const NativeType& new_payload_type,
-      const NativeType& new_container_type,
-      Zone* zone) const = 0;
+      const NativeType& new_container_type) const = 0;
 
 #if defined(TARGET_ARCH_ARM)
   const NativeLocation& WidenToQFpuRegister(Zone* zone) const;
@@ -101,7 +101,7 @@
   const NativeFpuRegistersLocation& AsFpuRegisters() const;
   const NativeStackLocation& AsStack() const;
 
-  virtual NativeLocation& Split(intptr_t index, Zone* zone) const {
+  virtual NativeLocation& Split(Zone* zone, intptr_t index) const {
     ASSERT(index == 0 || index == 1);
     UNREACHABLE();
   }
@@ -152,9 +152,9 @@
   virtual ~NativeRegistersLocation() {}
 
   virtual NativeRegistersLocation& WithOtherNativeType(
+      Zone* zone,
       const NativeType& new_payload_type,
-      const NativeType& new_container_type,
-      Zone* zone) const {
+      const NativeType& new_container_type) const {
     return *new (zone)
         NativeRegistersLocation(new_payload_type, new_container_type, regs_);
   }
@@ -167,7 +167,7 @@
   intptr_t num_regs() const { return regs_->length(); }
   Register reg_at(intptr_t index) const { return regs_->At(index); }
 
-  virtual NativeRegistersLocation& Split(intptr_t index, Zone* zone) const;
+  virtual NativeRegistersLocation& Split(Zone* zone, intptr_t index) const;
 
   virtual void PrintTo(BaseTextBuffer* f) const;
 
@@ -220,9 +220,9 @@
   virtual ~NativeFpuRegistersLocation() {}
 
   virtual NativeFpuRegistersLocation& WithOtherNativeType(
+      Zone* zone,
       const NativeType& new_payload_type,
-      const NativeType& new_container_type,
-      Zone* zone) const {
+      const NativeType& new_container_type) const {
     return *new (zone) NativeFpuRegistersLocation(
         new_payload_type, new_container_type, fpu_reg_kind_, fpu_reg_);
   }
@@ -276,9 +276,9 @@
   virtual ~NativeStackLocation() {}
 
   virtual NativeStackLocation& WithOtherNativeType(
+      Zone* zone,
       const NativeType& new_payload_type,
-      const NativeType& new_container_type,
-      Zone* zone) const {
+      const NativeType& new_container_type) const {
     return *new (zone) NativeStackLocation(new_payload_type, new_container_type,
                                            base_register_, offset_in_bytes_);
   }
@@ -301,7 +301,7 @@
     return Location::DoubleStackSlot(offset_in_words(), base_register_);
   }
 
-  virtual NativeStackLocation& Split(intptr_t index, Zone* zone) const;
+  virtual NativeStackLocation& Split(Zone* zone, intptr_t index) const;
 
   virtual void PrintTo(BaseTextBuffer* f) const;
 
diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc
index e4daa47..5bb9f4c 100644
--- a/runtime/vm/compiler/ffi/native_type.cc
+++ b/runtime/vm/compiler/ffi/native_type.cc
@@ -19,12 +19,12 @@
 
 namespace ffi {
 
-const NativeFundamentalType& NativeType::AsFundamental() const {
-  ASSERT(IsFundamental());
-  return static_cast<const NativeFundamentalType&>(*this);
+const NativePrimitiveType& NativeType::AsPrimitive() const {
+  ASSERT(IsPrimitive());
+  return static_cast<const NativePrimitiveType&>(*this);
 }
 
-bool NativeFundamentalType::IsInt() const {
+bool NativePrimitiveType::IsInt() const {
   switch (representation_) {
     case kInt8:
     case kUint8:
@@ -40,16 +40,16 @@
   }
 }
 
-bool NativeFundamentalType::IsFloat() const {
+bool NativePrimitiveType::IsFloat() const {
   return representation_ == kFloat || representation_ == kDouble ||
          representation_ == kHalfDouble;
 }
 
-bool NativeFundamentalType::IsVoid() const {
+bool NativePrimitiveType::IsVoid() const {
   return representation_ == kVoid;
 }
 
-bool NativeFundamentalType::IsSigned() const {
+bool NativePrimitiveType::IsSigned() const {
   ASSERT(IsInt() || IsFloat());
   switch (representation_) {
     case kInt8:
@@ -84,11 +84,11 @@
     0,  // kVoid,
 };
 
-intptr_t NativeFundamentalType::SizeInBytes() const {
+intptr_t NativePrimitiveType::SizeInBytes() const {
   return fundamental_size_in_bytes[representation_];
 }
 
-intptr_t NativeFundamentalType::AlignmentInBytesStack() const {
+intptr_t NativePrimitiveType::AlignmentInBytesStack() const {
   switch (CallingConventions::kArgumentStackAlignment) {
     case kAlignedToWordSize:
       // The default is to align stack arguments to word size.
@@ -108,7 +108,7 @@
   }
 }
 
-intptr_t NativeFundamentalType::AlignmentInBytesField() const {
+intptr_t NativePrimitiveType::AlignmentInBytesField() const {
   switch (CallingConventions::kFieldAlignment) {
     case kAlignedToValueSize:
       // The default is to align fields to their own size.
@@ -127,7 +127,7 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-bool NativeFundamentalType::IsExpressibleAsRepresentation() const {
+bool NativePrimitiveType::IsExpressibleAsRepresentation() const {
   switch (representation_) {
     case kInt8:
     case kUint8:
@@ -149,7 +149,7 @@
   }
 }
 
-Representation NativeFundamentalType::AsRepresentation() const {
+Representation NativePrimitiveType::AsRepresentation() const {
   ASSERT(IsExpressibleAsRepresentation());
   switch (representation_) {
     case kInt32:
@@ -171,14 +171,14 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-bool NativeFundamentalType::Equals(const NativeType& other) const {
-  if (!other.IsFundamental()) {
+bool NativePrimitiveType::Equals(const NativeType& other) const {
+  if (!other.IsPrimitive()) {
     return false;
   }
-  return other.AsFundamental().representation_ == representation_;
+  return other.AsPrimitive().representation_ == representation_;
 }
 
-static FundamentalType split_fundamental(FundamentalType in) {
+static PrimitiveType split_fundamental(PrimitiveType in) {
   switch (in) {
     case kInt16:
       return kInt8;
@@ -199,14 +199,14 @@
   }
 }
 
-NativeFundamentalType& NativeFundamentalType::Split(intptr_t index,
-                                                    Zone* zone) const {
+NativePrimitiveType& NativePrimitiveType::Split(Zone* zone,
+                                                intptr_t index) const {
   ASSERT(index == 0 || index == 1);
   auto new_rep = split_fundamental(representation());
-  return *new (zone) NativeFundamentalType(new_rep);
+  return *new (zone) NativePrimitiveType(new_rep);
 }
 
-static FundamentalType TypeRepresentation(classid_t class_id) {
+static PrimitiveType TypeRepresentation(classid_t class_id) {
   switch (class_id) {
     case kFfiInt8Cid:
       return kInt8;
@@ -242,19 +242,19 @@
   }
 }
 
-NativeType& NativeType::FromTypedDataClassId(classid_t class_id, Zone* zone) {
+NativeType& NativeType::FromTypedDataClassId(Zone* zone, classid_t class_id) {
   // TODO(36730): Support composites.
   const auto fundamental_rep = TypeRepresentation(class_id);
-  return *new (zone) NativeFundamentalType(fundamental_rep);
+  return *new (zone) NativePrimitiveType(fundamental_rep);
 }
 
-NativeType& NativeType::FromAbstractType(const AbstractType& type, Zone* zone) {
+NativeType& NativeType::FromAbstractType(Zone* zone, const AbstractType& type) {
   // TODO(36730): Support composites.
-  return NativeType::FromTypedDataClassId(type.type_class_id(), zone);
+  return NativeType::FromTypedDataClassId(zone, type.type_class_id());
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-static FundamentalType fundamental_rep(Representation rep) {
+static PrimitiveType fundamental_rep(Representation rep) {
   switch (rep) {
     case kUnboxedDouble:
       return kDouble;
@@ -272,9 +272,9 @@
   UNREACHABLE();
 }
 
-NativeFundamentalType& NativeType::FromUnboxedRepresentation(Representation rep,
-                                                             Zone* zone) {
-  return *new (zone) NativeFundamentalType(fundamental_rep(rep));
+NativePrimitiveType& NativeType::FromUnboxedRepresentation(Zone* zone,
+                                                           Representation rep) {
+  return *new (zone) NativePrimitiveType(fundamental_rep(rep));
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
@@ -285,7 +285,7 @@
   return Thread::Current()->zone()->MakeCopyOfString(buffer);
 }
 
-static const char* FundamentalTypeToCString(FundamentalType rep) {
+static const char* PrimitiveTypeToCString(PrimitiveType rep) {
   switch (rep) {
     case kInt8:
       return "int8";
@@ -320,16 +320,16 @@
   f->AddString("I");
 }
 
-void NativeFundamentalType::PrintTo(BaseTextBuffer* f) const {
-  f->Printf("%s", FundamentalTypeToCString(representation_));
+void NativePrimitiveType::PrintTo(BaseTextBuffer* f) const {
+  f->Printf("%s", PrimitiveTypeToCString(representation_));
 }
 
 const NativeType& NativeType::WidenTo4Bytes(Zone* zone) const {
   if (IsInt() && SizeInBytes() <= 2) {
     if (IsSigned()) {
-      return *new (zone) NativeFundamentalType(kInt32);
+      return *new (zone) NativePrimitiveType(kInt32);
     } else {
-      return *new (zone) NativeFundamentalType(kUint32);
+      return *new (zone) NativePrimitiveType(kUint32);
     }
   }
   return *this;
diff --git a/runtime/vm/compiler/ffi/native_type.h b/runtime/vm/compiler/ffi/native_type.h
index b0dc39b..66d5f31 100644
--- a/runtime/vm/compiler/ffi/native_type.h
+++ b/runtime/vm/compiler/ffi/native_type.h
@@ -23,7 +23,7 @@
 
 namespace ffi {
 
-class NativeFundamentalType;
+class NativePrimitiveType;
 
 // NativeTypes are the types used in calling convention specifications:
 // integers, floats, and composites.
@@ -38,29 +38,29 @@
 //
 // Instead, NativeTypes support representations not supported in Dart's unboxed
 // Representations, such as:
-// * Fundamental types (https://en.cppreference.com/w/cpp/language/types):
+// * Primitive types:
 //   * int8_t
 //   * int16_t
 //   * uint8_t
 //   * uint16t
 //   * void
-// * Compound types (https://en.cppreference.com/w/cpp/language/type):
+// * Compound types:
 //   * Struct
 //   * Union
 //
 // TODO(36730): Add composites.
 class NativeType : public ZoneAllocated {
  public:
-  static NativeType& FromAbstractType(const AbstractType& type, Zone* zone);
-  static NativeType& FromTypedDataClassId(classid_t class_id, Zone* zone);
+  static NativeType& FromAbstractType(Zone* zone, const AbstractType& type);
+  static NativeType& FromTypedDataClassId(Zone* zone, classid_t class_id);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static NativeFundamentalType& FromUnboxedRepresentation(Representation rep,
-                                                          Zone* zone);
+  static NativePrimitiveType& FromUnboxedRepresentation(Zone* zone,
+                                                        Representation rep);
 #endif
 
-  virtual bool IsFundamental() const { return false; }
-  const NativeFundamentalType& AsFundamental() const;
+  virtual bool IsPrimitive() const { return false; }
+  const NativePrimitiveType& AsPrimitive() const;
 
   virtual bool IsInt() const { return false; }
   virtual bool IsFloat() const { return false; }
@@ -96,7 +96,7 @@
   virtual bool Equals(const NativeType& other) const { UNREACHABLE(); }
 
   // Split representation in two.
-  virtual NativeType& Split(intptr_t index, Zone* zone) const { UNREACHABLE(); }
+  virtual NativeType& Split(Zone* zone, intptr_t index) const { UNREACHABLE(); }
 
   // If this is a 8 or 16 bit int, returns a 32 bit container.
   // Otherwise, return original representation.
@@ -111,7 +111,7 @@
   NativeType() {}
 };
 
-enum FundamentalType {
+enum PrimitiveType {
   kInt8,
   kUint8,
   kInt16,
@@ -127,13 +127,19 @@
   // TODO(37470): Add packed data structures.
 };
 
-class NativeFundamentalType : public NativeType {
+// Represents a primitive native type.
+//
+// These are called object types in the C standard (ISO/IEC 9899:2011) and
+// fundamental types in C++ (https://en.cppreference.com/w/cpp/language/types)
+// but more commonly these are called primitive types
+// (https://en.wikipedia.org/wiki/Primitive_data_type).
+class NativePrimitiveType : public NativeType {
  public:
-  explicit NativeFundamentalType(FundamentalType rep) : representation_(rep) {}
+  explicit NativePrimitiveType(PrimitiveType rep) : representation_(rep) {}
 
-  FundamentalType representation() const { return representation_; }
+  PrimitiveType representation() const { return representation_; }
 
-  virtual bool IsFundamental() const { return true; }
+  virtual bool IsPrimitive() const { return true; }
 
   virtual bool IsInt() const;
   virtual bool IsFloat() const;
@@ -151,14 +157,14 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   virtual bool Equals(const NativeType& other) const;
-  virtual NativeFundamentalType& Split(intptr_t part, Zone* zone) const;
+  virtual NativePrimitiveType& Split(Zone* zone, intptr_t part) const;
 
   virtual void PrintTo(BaseTextBuffer* f) const;
 
-  virtual ~NativeFundamentalType() {}
+  virtual ~NativePrimitiveType() {}
 
  private:
-  const FundamentalType representation_;
+  const PrimitiveType representation_;
 };
 
 }  // namespace ffi
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 7bcb54a..48aae11 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1255,7 +1255,7 @@
       const classid_t typed_data_cid =
           compiler::ffi::ElementTypedDataCid(ffi_type_arg_cid);
       const auto& native_rep = compiler::ffi::NativeType::FromTypedDataClassId(
-          ffi_type_arg_cid, zone_);
+          zone_, ffi_type_arg_cid);
 
       ASSERT(function.NumParameters() == 2);
       LocalVariable* arg_pointer = parsed_function_->RawParameterVariable(0);
@@ -1336,7 +1336,7 @@
       const classid_t typed_data_cid =
           compiler::ffi::ElementTypedDataCid(ffi_type_arg_cid);
       const auto& native_rep = compiler::ffi::NativeType::FromTypedDataClassId(
-          ffi_type_arg_cid, zone_);
+          zone_, ffi_type_arg_cid);
 
       LocalVariable* arg_pointer = parsed_function_->RawParameterVariable(0);
       LocalVariable* arg_offset = parsed_function_->RawParameterVariable(1);
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 26f8292..b3c99af 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -282,7 +282,7 @@
                                  /*enter_safepoint=*/true);
 
   __ popq(R12);
-  __ CallCFunction(RBX);
+  __ CallCFunction(RBX, /*restore_rsp=*/true);
 
   __ TransitionNativeToGenerated(/*leave_safepoint=*/true);
 
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index dc2e794..c1fb6c3 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -304,6 +304,16 @@
   // same time? (Windows no, rest yes)
   static const bool kArgumentIntRegXorFpuReg = true;
 
+  // > The x64 Application Binary Interface (ABI) uses a four-register
+  // > fast-call calling convention by default. Space is allocated on the call
+  // > stack as a shadow store for callees to save those registers.
+  // https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
+  //
+  // The caller allocates this space. The caller should also reclaim this space
+  // after the call to restore the stack to its original state if needed.
+  //
+  // This is also known as home space.
+  // https://devblogs.microsoft.com/oldnewthing/20160623-00/?p=93735
   static const intptr_t kShadowSpaceBytes = 4 * kWordSize;
 
   static const intptr_t kVolatileCpuRegisters =
diff --git a/tests/corelib/reg_exp_all_matches_test.dart b/tests/corelib/reg_exp_all_matches_test.dart
index 54fbf10..a289723 100644
--- a/tests/corelib/reg_exp_all_matches_test.dart
+++ b/tests/corelib/reg_exp_all_matches_test.dart
@@ -10,7 +10,7 @@
   static testIterator() {
     var matches = new RegExp("foo").allMatches("foo foo");
     Iterator it = matches.iterator;
-    if (isStrongMode) {
+    if (hasSoundNullSafety) {
       Expect.throws(() => it.current);
     } else {
       Expect.isNull(it.current);
diff --git a/tests/dart2js/internal/rti/required_named_parameters_test.dart b/tests/dart2js/internal/rti/required_named_parameters_test.dart
index c07f7a4..ccf3f7d 100644
--- a/tests/dart2js/internal/rti/required_named_parameters_test.dart
+++ b/tests/dart2js/internal/rti/required_named_parameters_test.dart
@@ -51,11 +51,13 @@
 
   // Subtype may not redeclare optional parameters as required
   rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b!A,c!A})");
-  Expect.equals(isWeakMode, rti.testingIsSubtype(universe, rti2, rti1));
+  Expect.equals(
+      hasUnsoundNullSafety, rti.testingIsSubtype(universe, rti2, rti1));
 
   // Subtype may not declare new required named parameters
   rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d!A})");
-  Expect.equals(isWeakMode, rti.testingIsSubtype(universe, rti2, rti1));
+  Expect.equals(
+      hasUnsoundNullSafety, rti.testingIsSubtype(universe, rti2, rti1));
 
   // Rti.toString() appears as expected
   Expect.equals('(B, {required B a, B b, required B c}) => dynamic',
diff --git a/tests/dart2js/internal/rti/subtype_test.dart b/tests/dart2js/internal/rti/subtype_test.dart
index 68f4de7..d4f0c48 100644
--- a/tests/dart2js/internal/rti/subtype_test.dart
+++ b/tests/dart2js/internal/rti/subtype_test.dart
@@ -78,7 +78,7 @@
 }
 
 void testNull() {
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     unrelated(nullName, 'int');
     unrelated(nullName, 'Iterable<CodeUnits>');
     unrelated(nullName, objectName);
@@ -93,7 +93,7 @@
 
 void testBottom() {
   String never = '0&';
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     strictSubtype(never, nullName);
   } else {
     equivalent(never, nullName);
diff --git a/tests/dart2js_2/internal/rti/required_named_parameters_test.dart b/tests/dart2js_2/internal/rti/required_named_parameters_test.dart
index c07f7a4..ccf3f7d 100644
--- a/tests/dart2js_2/internal/rti/required_named_parameters_test.dart
+++ b/tests/dart2js_2/internal/rti/required_named_parameters_test.dart
@@ -51,11 +51,13 @@
 
   // Subtype may not redeclare optional parameters as required
   rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b!A,c!A})");
-  Expect.equals(isWeakMode, rti.testingIsSubtype(universe, rti2, rti1));
+  Expect.equals(
+      hasUnsoundNullSafety, rti.testingIsSubtype(universe, rti2, rti1));
 
   // Subtype may not declare new required named parameters
   rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d!A})");
-  Expect.equals(isWeakMode, rti.testingIsSubtype(universe, rti2, rti1));
+  Expect.equals(
+      hasUnsoundNullSafety, rti.testingIsSubtype(universe, rti2, rti1));
 
   // Rti.toString() appears as expected
   Expect.equals('(B, {required B a, B b, required B c}) => dynamic',
diff --git a/tests/language/function_subtype/bound_closure5_test.dart b/tests/language/function_subtype/bound_closure5_test.dart
index 1844a42..d498a19 100644
--- a/tests/language/function_subtype/bound_closure5_test.dart
+++ b/tests/language/function_subtype/bound_closure5_test.dart
@@ -39,7 +39,7 @@
   new D<String, bool>().test('bool', true);
   new D<bool, int>().test('int', false);
   new D<Object, Object>().test('Object', false);
-  new D<Null, Null>().test('Null', isWeakMode);
+  new D<Null, Null>().test('Null', hasUnsoundNullSafety);
   new D<Never, Never>().test('Never', true);
   new D<dynamic, dynamic>().test('dynamic', false);
 }
diff --git a/tests/language/function_subtype/bound_closure5a_test.dart b/tests/language/function_subtype/bound_closure5a_test.dart
index 38b173d..b5d274b 100644
--- a/tests/language/function_subtype/bound_closure5a_test.dart
+++ b/tests/language/function_subtype/bound_closure5a_test.dart
@@ -41,7 +41,7 @@
   new D<String, bool>().test('bool', true);
   new D<bool, int>().test('int', false);
   new D<Object, Object>().test('Object', false);
-  new D<Null, Null>().test('Null', isWeakMode);
+  new D<Null, Null>().test('Null', hasUnsoundNullSafety);
   new D<Never, Never>().test('Never', true);
   new D<dynamic, dynamic>().test('dynamic', false);
 }
diff --git a/tests/language/function_subtype/bound_closure6_test.dart b/tests/language/function_subtype/bound_closure6_test.dart
index e26d21f..ea119a5 100644
--- a/tests/language/function_subtype/bound_closure6_test.dart
+++ b/tests/language/function_subtype/bound_closure6_test.dart
@@ -42,6 +42,6 @@
   new C<int>().test('int', false);
   new C<Object>().test('Object', false);
   new C<dynamic>().test('dynamic', false);
-  new C<Null>().test('Null', isWeakMode);
+  new C<Null>().test('Null', hasUnsoundNullSafety);
   new C<Never>().test('Never', true);
 }
diff --git a/tests/language/function_subtype/cast2_test.dart b/tests/language/function_subtype/cast2_test.dart
index 03a8f53..5e0f5b7 100644
--- a/tests/language/function_subtype/cast2_test.dart
+++ b/tests/language/function_subtype/cast2_test.dart
@@ -26,7 +26,7 @@
 void main() {
   new Class<dynamic>().test(false, bar, "dynamic");
   new Class<Object>().test(false, bar, "Object");
-  new Class<Null>().test(isWeakMode, bar, "Null");
+  new Class<Null>().test(hasUnsoundNullSafety, bar, "Null");
   new Class<Never>().test(true, bar, "Never");
   new Class<int>().test(true, bar, "int");
   new Class<bool>().test(false, bar, "bool");
diff --git a/tests/language/function_subtype/checked0_test.dart b/tests/language/function_subtype/checked0_test.dart
index a314529..40abf58 100644
--- a/tests/language/function_subtype/checked0_test.dart
+++ b/tests/language/function_subtype/checked0_test.dart
@@ -69,6 +69,6 @@
   new C<int>().test('int', false);
   new C<dynamic>().test('dynamic', false);
   new C<Object>().test('Object', false);
-  new C<Null>().test('Null', isWeakMode);
+  new C<Null>().test('Null', hasUnsoundNullSafety);
   new C<Never>().test('Null', true);
 }
diff --git a/tests/language/function_subtype/inline0_test.dart b/tests/language/function_subtype/inline0_test.dart
index 4e99998..c28d1d0 100644
--- a/tests/language/function_subtype/inline0_test.dart
+++ b/tests/language/function_subtype/inline0_test.dart
@@ -41,7 +41,7 @@
 }
 
 main() {
-  new C<bool>().test('bool', true, isWeakMode);
+  new C<bool>().test('bool', true, hasUnsoundNullSafety);
   new C<int>().test('int', false, false);
-  new C<dynamic>().test('dynamic', true, isWeakMode);
+  new C<dynamic>().test('dynamic', true, hasUnsoundNullSafety);
 }
diff --git a/tests/language/function_subtype/inline2_test.dart b/tests/language/function_subtype/inline2_test.dart
index a3f4078..2f63a3d 100644
--- a/tests/language/function_subtype/inline2_test.dart
+++ b/tests/language/function_subtype/inline2_test.dart
@@ -23,7 +23,7 @@
   testDynamicTypeError(false, () => f(m1), "'new C.$constructorName(m1)'");
   testDynamicTypeError(true, () => f(m2), "'new C.$constructorName(m2)'");
   testDynamicTypeError(
-      isStrongMode, () => f(m3), "'new C.$constructorName(m3)'");
+      hasSoundNullSafety, () => f(m3), "'new C.$constructorName(m3)'");
   testDynamicTypeError(true, () => f(m4), "'new C.$constructorName(m4)'");
   testDynamicTypeError(false, () => f(m5), "'new C.$constructorName(m5)'");
 }
diff --git a/tests/language/function_subtype/local2_test.dart b/tests/language/function_subtype/local2_test.dart
index 7b0d19d..fe3de21 100644
--- a/tests/language/function_subtype/local2_test.dart
+++ b/tests/language/function_subtype/local2_test.dart
@@ -38,6 +38,6 @@
   new C<int>().test('int', false);
   new C<dynamic>().test('dynamic', false);
   new C<Object>().test('Object', false);
-  new C<Null>().test('Null', isWeakMode);
+  new C<Null>().test('Null', hasUnsoundNullSafety);
   new C<Never>().test('Never', true);
 }
diff --git a/tests/language/function_subtype/local5_test.dart b/tests/language/function_subtype/local5_test.dart
index 92d570f..18c887c 100644
--- a/tests/language/function_subtype/local5_test.dart
+++ b/tests/language/function_subtype/local5_test.dart
@@ -40,6 +40,6 @@
   new D<bool, int>().test('int', false);
   new D<dynamic, dynamic>().test('dynamic', false);
   new D<Object, Object>().test('Object', false);
-  new D<Null, Null>().test('Null', isWeakMode);
+  new D<Null, Null>().test('Null', hasUnsoundNullSafety);
   new D<Never, Never>().test('Never', true);
 }
diff --git a/tests/language/function_subtype/not2_test.dart b/tests/language/function_subtype/not2_test.dart
index 03b0110..ffad8f7 100644
--- a/tests/language/function_subtype/not2_test.dart
+++ b/tests/language/function_subtype/not2_test.dart
@@ -22,7 +22,7 @@
 void main() {
   new Class<dynamic>().test(true, bar, "dynamic");
   new Class<Object>().test(true, bar, "Object");
-  new Class<Null>().test(isStrongMode, bar, "Null");
+  new Class<Null>().test(hasSoundNullSafety, bar, "Null");
   new Class<Never>().test(false, bar, "Never");
   new Class<int>().test(false, bar, "int");
   new Class<bool>().test(true, bar, "bool");
diff --git a/tests/language/function_subtype/not3_test.dart b/tests/language/function_subtype/not3_test.dart
index 0c03826..e3d23bc6 100644
--- a/tests/language/function_subtype/not3_test.dart
+++ b/tests/language/function_subtype/not3_test.dart
@@ -26,7 +26,7 @@
 void main() {
   new Class<dynamic>().test(true, bar, "dynamic");
   new Class<Object>().test(true, bar, "Object");
-  new Class<Null>().test(isStrongMode, bar, "Null");
+  new Class<Null>().test(hasSoundNullSafety, bar, "Null");
   new Class<Never>().test(false, bar, "Never");
   new Class<int>().test(false, bar, "int");
   new Class<bool>().test(true, bar, "bool");
diff --git a/tests/language/function_subtype/top_level1_test.dart b/tests/language/function_subtype/top_level1_test.dart
index 4e2d763..92aac32 100644
--- a/tests/language/function_subtype/top_level1_test.dart
+++ b/tests/language/function_subtype/top_level1_test.dart
@@ -40,6 +40,6 @@
   new C<int>().test('int', false);
   new C<Object>().test('Object', false);
   new C<dynamic>().test('dynamic', false);
-  new C<Null>().test('Null', isWeakMode);
+  new C<Null>().test('Null', hasUnsoundNullSafety);
   new C<Never>().test('Never', true);
 }
diff --git a/tests/language/generic/instanceof.dart b/tests/language/generic/instanceof.dart
index 547239c..d90b97e 100644
--- a/tests/language/generic/instanceof.dart
+++ b/tests/language/generic/instanceof.dart
@@ -56,7 +56,7 @@
     }
     {
       Foo foo = new Foo<List<Object>>();
-      Expect.equals(isWeakMode, foo.isT(new List.filled(5, null)));
+      Expect.equals(hasUnsoundNullSafety, foo.isT(new List.filled(5, null)));
       Expect.equals(true, foo.isT(new List<Object>.filled(5, "o")));
       Expect.equals(true, foo.isT(new List<int>.filled(5, 0)));
       Expect.equals(true, foo.isT(new List<num>.filled(5, 0)));
@@ -64,7 +64,7 @@
     }
     {
       Foo foo = new Foo<List<int>>();
-      Expect.equals(isWeakMode, foo.isT(new List.filled(5, null)));
+      Expect.equals(hasUnsoundNullSafety, foo.isT(new List.filled(5, null)));
       Expect.equals(false, foo.isT(new List<Object>.filled(5, "o")));
       Expect.equals(true, foo.isT(new List<int>.filled(5, 0)));
       Expect.equals(false, foo.isT(new List<num>.filled(5, 0)));
@@ -72,7 +72,7 @@
     }
     {
       Foo foo = new Foo<List<num>>();
-      Expect.equals(isWeakMode, foo.isT(new List.filled(5, null)));
+      Expect.equals(hasUnsoundNullSafety, foo.isT(new List.filled(5, null)));
       Expect.equals(false, foo.isT(new List<Object>.filled(5, "o")));
       Expect.equals(true, foo.isT(new List<int>.filled(5, 0)));
       Expect.equals(true, foo.isT(new List<num>.filled(5, 0)));
@@ -80,7 +80,7 @@
     }
     {
       Foo foo = new Foo<List<String>>();
-      Expect.equals(isWeakMode, foo.isT(new List.filled(5, null)));
+      Expect.equals(hasUnsoundNullSafety, foo.isT(new List.filled(5, null)));
       Expect.equals(false, foo.isT(new List<Object>.filled(5, "o")));
       Expect.equals(false, foo.isT(new List<int>.filled(5, 0)));
       Expect.equals(false, foo.isT(new List<num>.filled(5, 0)));
@@ -96,7 +96,8 @@
     }
     {
       Foo foo = new Foo<Object>();
-      Expect.equals(isWeakMode, foo.isListT(new List.filled(5, null)));
+      Expect.equals(
+          hasUnsoundNullSafety, foo.isListT(new List.filled(5, null)));
       Expect.equals(true, foo.isListT(new List<Object>.filled(5, "o")));
       Expect.equals(true, foo.isListT(new List<int>.filled(5, 0)));
       Expect.equals(true, foo.isListT(new List<num>.filled(5, 0)));
@@ -104,7 +105,8 @@
     }
     {
       Foo foo = new Foo<int>();
-      Expect.equals(isWeakMode, foo.isListT(new List.filled(5, null)));
+      Expect.equals(
+          hasUnsoundNullSafety, foo.isListT(new List.filled(5, null)));
       Expect.equals(false, foo.isListT(new List<Object>.filled(5, "o")));
       Expect.equals(true, foo.isListT(new List<int>.filled(5, 0)));
       Expect.equals(false, foo.isListT(new List<num>.filled(5, 0)));
@@ -112,7 +114,8 @@
     }
     {
       Foo foo = new Foo<num>();
-      Expect.equals(isWeakMode, foo.isListT(new List.filled(5, null)));
+      Expect.equals(
+          hasUnsoundNullSafety, foo.isListT(new List.filled(5, null)));
       Expect.equals(false, foo.isListT(new List<Object>.filled(5, "o")));
       Expect.equals(true, foo.isListT(new List<int>.filled(5, 0)));
       Expect.equals(true, foo.isListT(new List<num>.filled(5, 0)));
@@ -120,7 +123,8 @@
     }
     {
       Foo foo = new Foo<String>();
-      Expect.equals(isWeakMode, foo.isListT(new List.filled(5, null)));
+      Expect.equals(
+          hasUnsoundNullSafety, foo.isListT(new List.filled(5, null)));
       Expect.equals(false, foo.isListT(new List<Object>.filled(5, "o")));
       Expect.equals(false, foo.isListT(new List<int>.filled(5, 0)));
       Expect.equals(false, foo.isListT(new List<num>.filled(5, 0)));
diff --git a/tests/language/generic_methods/generic_class_tearoff_test.dart b/tests/language/generic_methods/generic_class_tearoff_test.dart
index 6c98ba8..28e9b8f 100644
--- a/tests/language/generic_methods/generic_class_tearoff_test.dart
+++ b/tests/language/generic_methods/generic_class_tearoff_test.dart
@@ -38,6 +38,6 @@
 
   Expect.isTrue(h is! Int2Int);
   Expect.isTrue(h is! String2String);
-  Expect.equals(isWeakMode, h is Object2Object);
+  Expect.equals(hasUnsoundNullSafety, h is Object2Object);
   Expect.isTrue(h is! GenericMethod);
 }
diff --git a/tests/language/is/is2_test.dart b/tests/language/is/is2_test.dart
index 93f6fb2..1d418b7 100644
--- a/tests/language/is/is2_test.dart
+++ b/tests/language/is/is2_test.dart
@@ -59,7 +59,7 @@
       var a = new List.empty();
       Expect.equals(true, a is List);
       Expect.equals(true, a is List<Object?>);
-      Expect.equals(isWeakMode, a is List<Object>);
+      Expect.equals(hasUnsoundNullSafety, a is List<Object>);
       Expect.equals(false, a is List<int>);
       Expect.equals(false, a is List<num>);
       Expect.equals(false, a is List<String>);
diff --git a/tests/language/nnbd/constant_null_safety_mode_test.dart b/tests/language/nnbd/constant_null_safety_mode_test.dart
index 131a2ff..6e89c75 100644
--- a/tests/language/nnbd/constant_null_safety_mode_test.dart
+++ b/tests/language/nnbd/constant_null_safety_mode_test.dart
@@ -5,15 +5,15 @@
 import 'package:expect/expect.dart';
 
 main() {
-  const trueInWeakMode = <Null>[] is List<int>;
-  Expect.equals(isWeakMode, trueInWeakMode);
+  const trueInNoSoundMode = <Null>[] is List<int>;
+  Expect.equals(hasUnsoundNullSafety, trueInNoSoundMode);
 
   // The following tests use the Uri.pathSegments() to access a constant list
   // that is defined in the SDK and verify the type associated with it does not
   // allow null when running with sound null safety.
   var emptyUri = Uri(pathSegments: []);
   dynamic stringList = emptyUri.pathSegments.toList();
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() {
       stringList.add(null);
     });
diff --git a/tests/language/null/null_test.dart b/tests/language/null/null_test.dart
index f13312d..48e9b25 100644
--- a/tests/language/null/null_test.dart
+++ b/tests/language/null/null_test.dart
@@ -145,13 +145,13 @@
 
   // Test cast, "as", operator.
   Expect.equals(null, null as Null);
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() => null as Object);
   } else {
     Expect.equals(null, null as Object);
   }
   Expect.equals(null, null as Object?);
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() => null as int);
   } else {
     Expect.equals(null, null as int);
@@ -163,13 +163,13 @@
   Expect.equals(null, new Generic<int?>().cast(null));
 
   Expect.equals(null, obj as Null);
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() => obj as Object);
   } else {
     Expect.equals(null, obj as Object);
   }
   Expect.equals(null, obj as Object?);
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() => obj as int);
   } else {
     Expect.equals(null, obj as int);
diff --git a/tests/language/regress/regress34147_test.dart b/tests/language/regress/regress34147_test.dart
index 20ab478..ab7197e 100644
--- a/tests/language/regress/regress34147_test.dart
+++ b/tests/language/regress/regress34147_test.dart
@@ -16,7 +16,7 @@
 }
 
 void expectError(Function() callback) {
-  if (isWeakMode) {
+  if (hasUnsoundNullSafety) {
     Expect.throwsAssertionError(callback);
   } else {
     Expect.throwsTypeError(callback);
diff --git a/tests/language/regress/regress41890_test.dart b/tests/language/regress/regress41890_test.dart
index 86e43a7..9374e28 100644
--- a/tests/language/regress/regress41890_test.dart
+++ b/tests/language/regress/regress41890_test.dart
@@ -43,8 +43,8 @@
       var item = items[i];
       String code = answers[i];
       bool expected = code == 'T' ||
-          (code == 'S' && isStrongMode) ||
-          (code == 'W' && isWeakMode);
+          (code == 'S' && hasSoundNullSafety) ||
+          (code == 'W' && hasUnsoundNullSafety);
       Expect.equals(expected, predicate(item), "$predicate '$code' $item");
     }
   }
diff --git a/tests/language/vm/bool_check_stack_traces_test.dart b/tests/language/vm/bool_check_stack_traces_test.dart
index bdc9ce5..e27da73 100644
--- a/tests/language/vm/bool_check_stack_traces_test.dart
+++ b/tests/language/vm/bool_check_stack_traces_test.dart
@@ -81,7 +81,7 @@
     print(stacktrace);
     print('-----------------------------');
 
-    if (isStrongMode) {
+    if (hasSoundNullSafety) {
       Expect.isTrue(e is TypeError);
       Expect.equals(
           "type 'Null' is not a subtype of type 'bool'", e.toString());
diff --git a/tests/lib/mirrors/null_test.dart b/tests/lib/mirrors/null_test.dart
index 0d58539..ab4c915 100644
--- a/tests/lib/mirrors/null_test.dart
+++ b/tests/lib/mirrors/null_test.dart
@@ -18,7 +18,7 @@
 
   InstanceMirror im1 = reflect(null);
   Expect.equals(cm, im1.type);
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() => im1.invoke(const Symbol("=="), [null]),
         'null not assignable to Object');
   } else {
@@ -29,7 +29,7 @@
   var obj = confuse(null); // Null value that isn't known at compile-time.
   InstanceMirror im2 = reflect(obj);
   Expect.equals(cm, im2.type);
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(() => im2.invoke(const Symbol("=="), [null]),
         'null not assignable to Object');
   } else {
@@ -41,7 +41,7 @@
   Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int);
   Expect.equals(null.hashCode, nullMirror.getField(#hashCode).reflectee);
   Expect.equals('Null', nullMirror.getField(#runtimeType).reflectee.toString());
-  if (isStrongMode) {
+  if (hasSoundNullSafety) {
     Expect.throwsTypeError(
         () => nullMirror.invoke(#==, [null]), 'null not assignable to Object');
   } else {
diff --git a/tools/VERSION b/tools/VERSION
index fd9047b..e96dbff 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 23
+PRERELEASE 24
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/patches/flutter-engine/a3815b659047cfc6b63d41d180aa1ca1b781ee68.patch b/tools/patches/flutter-engine/a3815b659047cfc6b63d41d180aa1ca1b781ee68.patch
deleted file mode 100644
index 94120c0..0000000
--- a/tools/patches/flutter-engine/a3815b659047cfc6b63d41d180aa1ca1b781ee68.patch
+++ /dev/null
@@ -1,596 +0,0 @@
-diff --git a/DEPS b/DEPS
-index 01113f340..e55da1cff 100644
---- a/DEPS
-+++ b/DEPS
-@@ -34,14 +34,14 @@ vars = {
-   # Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS.
-   # You can use //tools/dart/create_updated_flutter_deps.py to produce
-   # updated revision list of existing dependencies.
-   'dart_revision': 'a3815b659047cfc6b63d41d180aa1ca1b781ee68',
- 
-   # WARNING: DO NOT EDIT MANUALLY
-   # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py
-   'dart_args_tag': '1.6.0',
-   'dart_boringssl_gen_rev': '429ccb1877f7987a6f3988228bc2440e61293499',
-   'dart_boringssl_rev': '4dfd5af70191b068aebe567b8e29ce108cee85ce',
--  'dart_collection_rev': '80f5b6de8a8d8d584732a71bb59912da3e44883b',
-+  'dart_collection_rev': '583693680fc067e34ca5b72503df25e8b80579f9',
-   'dart_dart2js_info_tag': '0.6.0',
-   'dart_dart_style_tag': '1.3.6',
-   'dart_http_retry_tag': '0.1.1',
-@@ -49,7 +49,6 @@ vars = {
-   'dart_intl_tag': '0.16.1',
-   'dart_linter_tag': '0.1.117',
-   'dart_oauth2_tag': '1.6.0',
--  'dart_pedantic_tag': 'v1.9.0',
-   'dart_protobuf_rev': '3746c8fd3f2b0147623a8e3db89c3ff4330de760',
-   'dart_pub_rev': '04b054b62cc437cf23451785fdc50e49cd9de139',
-   'dart_pub_semver_tag': 'v1.4.4',
-@@ -61,15 +60,13 @@ vars = {
-   'dart_shelf_static_rev': 'v0.2.8',
-   'dart_shelf_tag': '0.7.3+3',
-   'dart_shelf_web_socket_tag': '0.2.2+3',
--  'dart_source_map_stack_trace_tag': '2.0.0',
--  'dart_source_span_tag': '1.7.0',
-   'dart_sse_tag': 'e5cf68975e8e87171a3dc297577aa073454a91dc',
--  'dart_stack_trace_tag': '56811dbb2530d823b764fe167ec335879a4adb32',
-+  'dart_stack_trace_tag': 'd3813ca0a77348e0faf0d6af0cc17913e36afa39',
-   'dart_stagehand_tag': 'v3.3.9',
--  'dart_stream_channel_tag': '70433d577be02c48cb16d72d65654f3b4d82c6ed',
-+  'dart_stream_channel_tag': 'c446774fd077c9bdbd6235a7aadc661ef60a9727',
-   'dart_test_reflective_loader_tag': '0.1.9',
-   'dart_tflite_native_rev': '3c777c40608a2a9f1427bfe0028ab48e7116b4c1',
--  'dart_typed_data_tag': '0c369b73a9b7ebf042c06512951bfe5b52b84a5f',
-+  'dart_typed_data_tag': 'f94fc57b8e8c0e4fe4ff6cfd8290b94af52d3719',
-   'dart_usage_tag': '3.4.0',
-   'dart_watcher_rev': 'fc3c9aae5d31d707b3013b42634dde8d8a1161b4',
- 
-@@ -171,13 +168,13 @@ deps = {
-    Var('dart_git') + '/args.git' + '@' + Var('dart_args_tag'),
- 
-   'src/third_party/dart/third_party/pkg/async':
--   Var('dart_git') + '/async.git@6b90f4557f330e1ead021f501ee7f1d8b0e77815',
-+   Var('dart_git') + '/async.git@128c461a97dbdbd9336ba000ba5a5c02e79b8651',
- 
-   'src/third_party/dart/third_party/pkg/bazel_worker':
-    Var('dart_git') + '/bazel_worker.git@26680d5e249b249c7216ab2fed0ac8ed4ee285c5',
- 
-   'src/third_party/dart/third_party/pkg/boolean_selector':
--   Var('dart_git') + '/boolean_selector.git@1309eabed510cc3b7536fd4367d39b97ebee3d69',
-+   Var('dart_git') + '/boolean_selector.git@665e6921ab246569420376f827bff4585dff0b14',
- 
-   'src/third_party/dart/third_party/pkg/charcode':
-    Var('dart_git') + '/charcode.git@af1e2d59a9c383da94f99ea51dac4b93fb0626c4',
-@@ -207,7 +204,7 @@ deps = {
-    Var('dart_git') + '/ffi.git@454ab0f9ea6bd06942a983238d8a6818b1357edb',
- 
-   'src/third_party/dart/third_party/pkg/fixnum':
--   Var('dart_git') + '/fixnum.git@9b38f49f6679654d66a363e69e48173cca07e882',
-+   Var('dart_git') + '/fixnum.git@300c3f025e94a72b7b6770e15f76a4de15f77668',
- 
-   'src/third_party/dart/third_party/pkg/glob':
-    Var('dart_git') + '/glob.git@e9f4e6b7ae8abe5071461cf8f47191bb19cf7ef6',
-@@ -246,7 +243,7 @@ deps = {
-    Var('dart_git') + '/markdown.git@dd150bb64c5f3b41d31f20f399ae2a855f7f8c00',
- 
-   'src/third_party/dart/third_party/pkg/matcher':
--   Var('dart_git') + '/matcher.git@8f8d965933c94a489b1a39e20d558a32841bfa5b',
-+   Var('dart_git') + '/matcher.git@9cae8faa7868bf3a88a7ba45eb0bd128e66ac515',
- 
-   'src/third_party/dart/third_party/pkg/mime':
-    Var('dart_git') + '/mime.git@179b5e6a88f4b63f36dc1b8fcbc1e83e5e0cd3a7',
-@@ -261,13 +258,13 @@ deps = {
-    Var('dart_git') + '/oauth2.git' + '@' + Var('dart_oauth2_tag'),
- 
-   'src/third_party/dart/third_party/pkg/path':
--   Var('dart_git') + '/path.git@4f3bb71843fe5493ba490828a1721821d7b33746',
-+   Var('dart_git') + '/path.git@62ecd5a78ffe5734d14ed0df76d20309084cd04a',
- 
-   'src/third_party/dart/third_party/pkg/pedantic':
--   Var('dart_git') + '/pedantic.git' + '@' + Var('dart_pedantic_tag'),
-+   Var('dart_git') + '/pedantic.git@24b38df72430d7e21cb4257828580becb9a39c72',
- 
-   'src/third_party/dart/third_party/pkg/pool':
--   Var('dart_git') + '/pool.git@86fbb2cde9bbc66c8d159909d2f65a5981ea5b50',
-+   Var('dart_git') + '/pool.git@eedbd5fde84f9a1a8da643b475305a81841da599',
- 
-   'src/third_party/dart/third_party/pkg/protobuf':
-    Var('dart_git') + '/protobuf.git' + '@' + Var('dart_protobuf_rev'),
-@@ -300,13 +297,13 @@ deps = {
-    Var('dart_git') + '/shelf_web_socket.git' + '@' + Var('dart_shelf_web_socket_tag'),
- 
-   'src/third_party/dart/third_party/pkg/source_map_stack_trace':
--   Var('dart_git') + '/source_map_stack_trace.git' + '@' + Var('dart_source_map_stack_trace_tag'),
-+   Var('dart_git') + '/source_map_stack_trace.git@1c3026f69d9771acf2f8c176a1ab750463309cce',
- 
-   'src/third_party/dart/third_party/pkg/source_maps':
--   Var('dart_git') + '/source_maps.git@87b4fd9027378bbd51b02e9d7df794eee8a82b7a',
-+   Var('dart_git') + '/source_maps.git@53eb92ccfe6e64924054f83038a534b959b12b3e',
- 
-   'src/third_party/dart/third_party/pkg/source_span':
--   Var('dart_git') + '/source_span.git' + '@' + Var('dart_source_span_tag'),
-+   Var('dart_git') + '/source_span.git@94833d6cbf4552ebe5d2aa6714acecd93834e53a',
- 
-   'src/third_party/dart/third_party/pkg/sse':
-    Var('dart_git') + '/sse.git' + '@' + Var('dart_sse_tag'),
-@@ -321,13 +318,13 @@ deps = {
-    Var('dart_git') + '/stream_channel.git' + '@' + Var('dart_stream_channel_tag'),
- 
-   'src/third_party/dart/third_party/pkg/string_scanner':
--   Var('dart_git') + '/string_scanner.git@a918e7371af6b6e73bfd534ff9da6084741c1f99',
-+   Var('dart_git') + '/string_scanner.git@1b63e6e5db5933d7be0a45da6e1129fe00262734',
- 
-   'src/third_party/dart/third_party/pkg/term_glyph':
--   Var('dart_git') + '/term_glyph.git@b3da31e9684a99cfe5f192b89914492018b44da7',
-+   Var('dart_git') + '/term_glyph.git@6a0f9b6fb645ba75e7a00a4e20072678327a0347',
- 
-   'src/third_party/dart/third_party/pkg/test':
--   Var('dart_git') + '/test.git@718fe6f93c4655208460f28e89d887c5ef4144c5',
-+   Var('dart_git') + '/test.git@c6b3fe63eda87da1687580071cad1eefd575f851',
- 
-   'src/third_party/dart/third_party/pkg/test_reflective_loader':
-    Var('dart_git') + '/test_reflective_loader.git' + '@' + Var('dart_test_reflective_loader_tag'),
-@@ -357,7 +354,7 @@ deps = {
-    Var('dart_git') + '/package_config.git@9c586d04bd26fef01215fd10e7ab96a3050cfa64',
- 
-   'src/third_party/dart/tools/sdks':
--   {'packages': [{'version': 'version:2.9.0-21.0.dev', 'package': 'dart/dart-sdk/${{platform}}'}], 'dep_type': 'cipd'},
-+   {'packages': [{'version': 'version:2.10.0-0.2-preview', 'package': 'dart/dart-sdk/${{platform}}'}], 'dep_type': 'cipd'},
- 
-   # WARNING: end of dart dependencies list that is cleaned up automatically - see create_updated_flutter_deps.py.
- 
-diff --git a/lib/ui/annotations.dart b/lib/ui/annotations.dart
-index 45d8ca6cc..b300af073 100644
---- a/lib/ui/annotations.dart
-+++ b/lib/ui/annotations.dart
-@@ -4,7 +4,7 @@
- 
- // TODO(dnfield): Remove unused_import ignores when https://github.com/dart-lang/sdk/issues/35164 is resolved.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/channel_buffers.dart b/lib/ui/channel_buffers.dart
-index cb32c4581..39d31d271 100644
---- a/lib/ui/channel_buffers.dart
-+++ b/lib/ui/channel_buffers.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart
-index ea3c0b714..4e0553936 100644
---- a/lib/ui/compositing.dart
-+++ b/lib/ui/compositing.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/geometry.dart b/lib/ui/geometry.dart
-index 2739048e7..a7404996c 100644
---- a/lib/ui/geometry.dart
-+++ b/lib/ui/geometry.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/hash_codes.dart b/lib/ui/hash_codes.dart
-index a6ede7849..7da175a27 100644
---- a/lib/ui/hash_codes.dart
-+++ b/lib/ui/hash_codes.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart
-index ff2dcaa12..39bab1240 100644
---- a/lib/ui/hooks.dart
-+++ b/lib/ui/hooks.dart
-@@ -4,7 +4,7 @@
- 
- // TODO(dnfield): Remove unused_import ignores when https://github.com/dart-lang/sdk/issues/35164 is resolved.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/isolate_name_server.dart b/lib/ui/isolate_name_server.dart
-index d976e0ac2..4b5c2c84d 100644
---- a/lib/ui/isolate_name_server.dart
-+++ b/lib/ui/isolate_name_server.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/lerp.dart b/lib/ui/lerp.dart
-index db9f7b2ec..0bb0a08b7 100644
---- a/lib/ui/lerp.dart
-+++ b/lib/ui/lerp.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/natives.dart b/lib/ui/natives.dart
-index ce29fe15c..0f2939592 100644
---- a/lib/ui/natives.dart
-+++ b/lib/ui/natives.dart
-@@ -4,7 +4,7 @@
- 
- // TODO(dnfield): remove unused_element ignores when https://github.com/dart-lang/sdk/issues/35164 is resolved.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart
-index 992db71cf..2599f90e2 100644
---- a/lib/ui/painting.dart
-+++ b/lib/ui/painting.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/plugins.dart b/lib/ui/plugins.dart
-index 64eca6e04..9622852fd 100644
---- a/lib/ui/plugins.dart
-+++ b/lib/ui/plugins.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/pointer.dart b/lib/ui/pointer.dart
-index 3c12cb971..3c8ffefaf 100644
---- a/lib/ui/pointer.dart
-+++ b/lib/ui/pointer.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/semantics.dart b/lib/ui/semantics.dart
-index bee542328..518a69412 100644
---- a/lib/ui/semantics.dart
-+++ b/lib/ui/semantics.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/text.dart b/lib/ui/text.dart
-index 8bdc0f05d..c246731d8 100644
---- a/lib/ui/text.dart
-+++ b/lib/ui/text.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- 
- part of dart.ui;
- 
-diff --git a/lib/ui/ui.dart b/lib/ui/ui.dart
-index 7612cf509..fe0e4fa16 100644
---- a/lib/ui/ui.dart
-+++ b/lib/ui/ui.dart
-@@ -9,7 +9,7 @@
- /// This library exposes the lowest-level services that Flutter frameworks use
- /// to bootstrap applications, such as classes for driving the input, graphics
- /// text, layout, and rendering subsystems.
--// @dart = 2.9
-+// @dart = 2.10
- library dart.ui;
- 
- import 'dart:_internal' hide Symbol; // ignore: unused_import
-diff --git a/lib/ui/window.dart b/lib/ui/window.dart
-index 815bee5a1..22f9ed0c3 100644
---- a/lib/ui/window.dart
-+++ b/lib/ui/window.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of dart.ui;
- 
- /// Signature of callbacks that have no arguments and return no data.
-diff --git a/lib/web_ui/lib/src/ui/annotations.dart b/lib/web_ui/lib/src/ui/annotations.dart
-index 977ca70ca..7dac0c567 100644
---- a/lib/web_ui/lib/src/ui/annotations.dart
-+++ b/lib/web_ui/lib/src/ui/annotations.dart
-@@ -4,7 +4,7 @@
- 
- // TODO(dnfield): Remove unused_import ignores when https://github.com/dart-lang/sdk/issues/35164 is resolved.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- // TODO(dnfield): Update this if/when we default this to on in the tool,
-diff --git a/lib/web_ui/lib/src/ui/canvas.dart b/lib/web_ui/lib/src/ui/canvas.dart
-index 1061ab718..ee185ef29 100644
---- a/lib/web_ui/lib/src/ui/canvas.dart
-+++ b/lib/web_ui/lib/src/ui/canvas.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Defines how a list of points is interpreted when drawing a set of points.
-diff --git a/lib/web_ui/lib/src/ui/channel_buffers.dart b/lib/web_ui/lib/src/ui/channel_buffers.dart
-index 5d3db5da5..6ce0bc962 100644
---- a/lib/web_ui/lib/src/ui/channel_buffers.dart
-+++ b/lib/web_ui/lib/src/ui/channel_buffers.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// A saved platform message for a channel with its callback.
-diff --git a/lib/web_ui/lib/src/ui/compositing.dart b/lib/web_ui/lib/src/ui/compositing.dart
-index 635dd7261..11a0e1199 100644
---- a/lib/web_ui/lib/src/ui/compositing.dart
-+++ b/lib/web_ui/lib/src/ui/compositing.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// An opaque object representing a composited scene.
-diff --git a/lib/web_ui/lib/src/ui/geometry.dart b/lib/web_ui/lib/src/ui/geometry.dart
-index 904cec065..c528c8c73 100644
---- a/lib/web_ui/lib/src/ui/geometry.dart
-+++ b/lib/web_ui/lib/src/ui/geometry.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Base class for [Size] and [Offset], which are both ways to describe
-diff --git a/lib/web_ui/lib/src/ui/hash_codes.dart b/lib/web_ui/lib/src/ui/hash_codes.dart
-index 69aeb33bb..e91fb1cc5 100644
---- a/lib/web_ui/lib/src/ui/hash_codes.dart
-+++ b/lib/web_ui/lib/src/ui/hash_codes.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- class _HashEnd { const _HashEnd(); }
-diff --git a/lib/web_ui/lib/src/ui/initialization.dart b/lib/web_ui/lib/src/ui/initialization.dart
-index 2749fa9e5..6865da812 100644
---- a/lib/web_ui/lib/src/ui/initialization.dart
-+++ b/lib/web_ui/lib/src/ui/initialization.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Initializes the platform.
-diff --git a/lib/web_ui/lib/src/ui/lerp.dart b/lib/web_ui/lib/src/ui/lerp.dart
-index bcc278f8a..5cd4c8ac1 100644
---- a/lib/web_ui/lib/src/ui/lerp.dart
-+++ b/lib/web_ui/lib/src/ui/lerp.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Linearly interpolate between two numbers.
-diff --git a/lib/web_ui/lib/src/ui/natives.dart b/lib/web_ui/lib/src/ui/natives.dart
-index e4bf1a2f5..4763db34e 100644
---- a/lib/web_ui/lib/src/ui/natives.dart
-+++ b/lib/web_ui/lib/src/ui/natives.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- // Corelib 'print' implementation.
-diff --git a/lib/web_ui/lib/src/ui/painting.dart b/lib/web_ui/lib/src/ui/painting.dart
-index a9bd10662..67da1842f 100644
---- a/lib/web_ui/lib/src/ui/painting.dart
-+++ b/lib/web_ui/lib/src/ui/painting.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- // ignore: unused_element, Used in Shader assert.
-diff --git a/lib/web_ui/lib/src/ui/path.dart b/lib/web_ui/lib/src/ui/path.dart
-index 18e351f53..1514d2432 100644
---- a/lib/web_ui/lib/src/ui/path.dart
-+++ b/lib/web_ui/lib/src/ui/path.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// A complex, one-dimensional subset of a plane.
-diff --git a/lib/web_ui/lib/src/ui/path_metrics.dart b/lib/web_ui/lib/src/ui/path_metrics.dart
-index 6d54888c2..b65e2b928 100644
---- a/lib/web_ui/lib/src/ui/path_metrics.dart
-+++ b/lib/web_ui/lib/src/ui/path_metrics.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// An iterable collection of [PathMetric] objects describing a [Path].
-diff --git a/lib/web_ui/lib/src/ui/pointer.dart b/lib/web_ui/lib/src/ui/pointer.dart
-index 698badcc4..e2f351caf 100644
---- a/lib/web_ui/lib/src/ui/pointer.dart
-+++ b/lib/web_ui/lib/src/ui/pointer.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// How the pointer has changed since the last report.
-diff --git a/lib/web_ui/lib/src/ui/semantics.dart b/lib/web_ui/lib/src/ui/semantics.dart
-index c6dffe2fc..a0fde9a5b 100644
---- a/lib/web_ui/lib/src/ui/semantics.dart
-+++ b/lib/web_ui/lib/src/ui/semantics.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// The possible actions that can be conveyed from the operating system
-diff --git a/lib/web_ui/lib/src/ui/test_embedding.dart b/lib/web_ui/lib/src/ui/test_embedding.dart
-index f72a5c75e..955dbfe53 100644
---- a/lib/web_ui/lib/src/ui/test_embedding.dart
-+++ b/lib/web_ui/lib/src/ui/test_embedding.dart
-@@ -4,7 +4,7 @@
- 
- // TODO(flutter_web): the Web-only API below need to be cleaned up.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Used to track when the platform is initialized. This ensures the test fonts
-diff --git a/lib/web_ui/lib/src/ui/text.dart b/lib/web_ui/lib/src/ui/text.dart
-index ec9a45943..58698d862 100644
---- a/lib/web_ui/lib/src/ui/text.dart
-+++ b/lib/web_ui/lib/src/ui/text.dart
-@@ -3,7 +3,7 @@
- // found in the LICENSE file.
- // Synced 2019-05-30T14:20:57.833907.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Whether to slant the glyphs in the font
-diff --git a/lib/web_ui/lib/src/ui/tile_mode.dart b/lib/web_ui/lib/src/ui/tile_mode.dart
-index 8fd24ae58..9ce9ddf3c 100644
---- a/lib/web_ui/lib/src/ui/tile_mode.dart
-+++ b/lib/web_ui/lib/src/ui/tile_mode.dart
-@@ -2,7 +2,7 @@
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Defines what happens at the edge of the gradient.
-diff --git a/lib/web_ui/lib/src/ui/window.dart b/lib/web_ui/lib/src/ui/window.dart
-index 557e6aa84..fd9e66740 100644
---- a/lib/web_ui/lib/src/ui/window.dart
-+++ b/lib/web_ui/lib/src/ui/window.dart
-@@ -3,7 +3,7 @@
- // found in the LICENSE file.
- // Synced 2019-05-30T14:20:57.841444.
- 
--// @dart = 2.9
-+// @dart = 2.10
- part of ui;
- 
- /// Signature of callbacks that have no arguments and return no data.
-diff --git a/lib/web_ui/lib/ui.dart b/lib/web_ui/lib/ui.dart
-index 49217e14a..13d5ee281 100644
---- a/lib/web_ui/lib/ui.dart
-+++ b/lib/web_ui/lib/ui.dart
-@@ -5,7 +5,7 @@
- /// This library defines the web equivalent of the native dart:ui.
- ///
- /// All types in this library are public.
--// @dart = 2.9
-+// @dart = 2.10
- library ui;
- 
- import 'dart:async';
diff --git a/tools/patches/flutter-engine/d2577410a5016eadc111919355e19d42dd45d816.patch b/tools/patches/flutter-engine/d2577410a5016eadc111919355e19d42dd45d816.patch
deleted file mode 100644
index c7446e9..0000000
--- a/tools/patches/flutter-engine/d2577410a5016eadc111919355e19d42dd45d816.patch
+++ /dev/null
@@ -1,804 +0,0 @@
-diff --git a/BUILD.gn b/BUILD.gn
-index edbeb6803..e280ae901 100644
---- a/BUILD.gn
-+++ b/BUILD.gn
-@@ -98,6 +98,7 @@ group("flutter") {
-       "//flutter/shell/platform/embedder:embedder_proctable_unittests",
-       "//flutter/shell/platform/embedder:embedder_unittests",
-       "//flutter/testing:testing_unittests",
-+      "//flutter/third_party/tonic/tests:tonic_unittests",
-       "//flutter/third_party/txt:txt_unittests",
-     ]
- 
-diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
-index f13271aa9..6b84f6a83 100755
---- a/ci/licenses_golden/licenses_flutter
-+++ b/ci/licenses_golden/licenses_flutter
-@@ -1463,6 +1463,8 @@ FILE: ../../../flutter/third_party/tonic/dart_persistent_value.cc
- FILE: ../../../flutter/third_party/tonic/dart_persistent_value.h
- FILE: ../../../flutter/third_party/tonic/dart_state.cc
- FILE: ../../../flutter/third_party/tonic/dart_state.h
-+FILE: ../../../flutter/third_party/tonic/dart_weak_persistent_value.cc
-+FILE: ../../../flutter/third_party/tonic/dart_weak_persistent_value.h
- FILE: ../../../flutter/third_party/tonic/dart_wrappable.cc
- FILE: ../../../flutter/third_party/tonic/dart_wrappable.h
- FILE: ../../../flutter/third_party/tonic/dart_wrapper_info.h
-diff --git a/lib/ui/painting/image_decoder.cc b/lib/ui/painting/image_decoder.cc
-index d6c4a668f..b6ffb20f5 100644
---- a/lib/ui/painting/image_decoder.cc
-+++ b/lib/ui/painting/image_decoder.cc
-@@ -224,12 +224,13 @@ void ImageDecoder::Decode(fml::RefPtr<ImageDescriptor> descriptor,
-   FML_DCHECK(callback);
-   FML_DCHECK(runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());
- 
--  // Always service the callback on the UI thread.
--  auto result = [callback, ui_runner = runners_.GetUITaskRunner()](
-+  // Always service the callback (and cleanup the descriptor) on the UI thread.
-+  auto result = [callback, descriptor, ui_runner = runners_.GetUITaskRunner()](
-                     SkiaGPUObject<SkImage> image,
-                     fml::tracing::TraceFlow flow) {
--    ui_runner->PostTask(fml::MakeCopyable(
--        [callback, image = std::move(image), flow = std::move(flow)]() mutable {
-+    ui_runner->PostTask(
-+        fml::MakeCopyable([callback, descriptor, image = std::move(image),
-+                           flow = std::move(flow)]() mutable {
-           // We are going to terminate the trace flow here. Flows cannot
-           // terminate without a base trace. Add one explicitly.
-           TRACE_EVENT0("flutter", "ImageDecodeCallback");
-diff --git a/lib/ui/painting/image_encoding.cc b/lib/ui/painting/image_encoding.cc
-index c17a784c5..8a7653f0b 100644
---- a/lib/ui/painting/image_encoding.cc
-+++ b/lib/ui/painting/image_encoding.cc
-@@ -35,9 +35,7 @@ enum ImageByteFormat {
-   kPNG,
- };
- 
--void FinalizeSkData(void* isolate_callback_data,
--                    Dart_WeakPersistentHandle handle,
--                    void* peer) {
-+void FinalizeSkData(void* isolate_callback_data, void* peer) {
-   SkData* buffer = reinterpret_cast<SkData*>(peer);
-   buffer->unref();
- }
-diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc
-index b834957a9..8a6215110 100644
---- a/runtime/dart_isolate.cc
-+++ b/runtime/dart_isolate.cc
-@@ -981,6 +981,11 @@ void DartIsolate::AddIsolateShutdownCallback(const fml::closure& closure) {
- }
- 
- void DartIsolate::OnShutdownCallback() {
-+  tonic::DartState* state = tonic::DartState::Current();
-+  if (state != nullptr) {
-+    state->SetIsShuttingDown();
-+  }
-+
-   {
-     tonic::DartApiScope api_scope;
-     Dart_Handle sticky_error = Dart_GetStickyError();
-diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc
-index ae9849a5a..b0c61a1b5 100644
---- a/shell/platform/embedder/embedder.cc
-+++ b/shell/platform/embedder/embedder.cc
-@@ -1922,8 +1922,7 @@ FlutterEngineResult FlutterEnginePostDartObject(
-         dart_object.value.as_external_typed_data.data = buffer;
-         dart_object.value.as_external_typed_data.peer = peer;
-         dart_object.value.as_external_typed_data.callback =
--            +[](void* unused_isolate_callback_data,
--                Dart_WeakPersistentHandle unused_handle, void* peer) {
-+            +[](void* unused_isolate_callback_data, void* peer) {
-               auto typed_peer = reinterpret_cast<ExternalTypedDataPeer*>(peer);
-               typed_peer->trampoline(typed_peer->user_data);
-               delete typed_peer;
-diff --git a/shell/platform/fuchsia/dart_runner/dart_runner.cc b/shell/platform/fuchsia/dart_runner/dart_runner.cc
-index 76d85405a..415d2885c 100644
---- a/shell/platform/fuchsia/dart_runner/dart_runner.cc
-+++ b/shell/platform/fuchsia/dart_runner/dart_runner.cc
-@@ -86,6 +86,10 @@ void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
-     tonic::DartMicrotaskQueue::GetForCurrentThread()->Destroy();
-     async_loop_quit(loop);
-   }
-+
-+  auto state =
-+      static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
-+  state->get()->SetIsShuttingDown();
- }
- 
- void IsolateGroupCleanupCallback(void* isolate_group_data) {
-diff --git a/testing/run_tests.py b/testing/run_tests.py
-index 06b8256d0..8bdd114f4 100755
---- a/testing/run_tests.py
-+++ b/testing/run_tests.py
-@@ -132,6 +132,8 @@ def RunCCTests(build_dir, filter):
- 
-   RunEngineExecutable(build_dir, 'runtime_unittests', filter, shuffle_flags)
- 
-+  RunEngineExecutable(build_dir, 'tonic_unittests', filter, shuffle_flags)
-+
-   if not IsWindows():
-     # https://github.com/flutter/flutter/issues/36295
-     RunEngineExecutable(build_dir, 'shell_unittests', filter, shuffle_flags)
-diff --git a/third_party/tonic/BUILD.gn b/third_party/tonic/BUILD.gn
-index f5bedda8d..9a6abda8b 100644
---- a/third_party/tonic/BUILD.gn
-+++ b/third_party/tonic/BUILD.gn
-@@ -35,6 +35,8 @@ source_set("tonic") {
-     "dart_persistent_value.h",
-     "dart_state.cc",
-     "dart_state.h",
-+    "dart_weak_persistent_value.cc",
-+    "dart_weak_persistent_value.h",
-     "dart_wrappable.cc",
-     "dart_wrappable.h",
-     "dart_wrapper_info.h",
-diff --git a/third_party/tonic/dart_state.cc b/third_party/tonic/dart_state.cc
-index b711a2297..3f37685c5 100644
---- a/third_party/tonic/dart_state.cc
-+++ b/third_party/tonic/dart_state.cc
-@@ -27,7 +27,8 @@ DartState::DartState(int dirfd,
-       message_handler_(new DartMessageHandler()),
-       file_loader_(new FileLoader(dirfd)),
-       message_epilogue_(message_epilogue),
--      has_set_return_code_(false) {}
-+      has_set_return_code_(false),
-+      is_shutting_down_(false) {}
- 
- DartState::~DartState() {}
- 
-diff --git a/third_party/tonic/dart_state.h b/third_party/tonic/dart_state.h
-index 845914937..1984a66bf 100644
---- a/third_party/tonic/dart_state.h
-+++ b/third_party/tonic/dart_state.h
-@@ -5,6 +5,7 @@
- #ifndef LIB_TONIC_DART_STATE_H_
- #define LIB_TONIC_DART_STATE_H_
- 
-+#include <atomic>
- #include <functional>
- #include <memory>
- 
-@@ -68,6 +69,9 @@ class DartState : public std::enable_shared_from_this<DartState> {
-   void SetReturnCodeCallback(std::function<void(uint32_t)> callback);
-   bool has_set_return_code() const { return has_set_return_code_; }
- 
-+  void SetIsShuttingDown() { is_shutting_down_ = true; }
-+  bool IsShuttingDown() { return is_shutting_down_; }
-+
-   virtual void DidSetIsolate();
- 
-   static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag,
-@@ -83,6 +87,7 @@ class DartState : public std::enable_shared_from_this<DartState> {
-   std::function<void(Dart_Handle)> message_epilogue_;
-   std::function<void(uint32_t)> set_return_code_callback_;
-   bool has_set_return_code_;
-+  std::atomic<bool> is_shutting_down_;
- 
-  protected:
-   TONIC_DISALLOW_COPY_AND_ASSIGN(DartState);
-diff --git a/third_party/tonic/dart_weak_persistent_value.cc b/third_party/tonic/dart_weak_persistent_value.cc
-new file mode 100644
-index 000000000..a2664d3e0
---- /dev/null
-+++ b/third_party/tonic/dart_weak_persistent_value.cc
-@@ -0,0 +1,70 @@
-+// Copyright 2013 The Flutter Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "tonic/dart_weak_persistent_value.h"
-+
-+#include "tonic/dart_state.h"
-+#include "tonic/scopes/dart_isolate_scope.h"
-+
-+namespace tonic {
-+
-+DartWeakPersistentValue::DartWeakPersistentValue() : handle_(nullptr) {}
-+
-+DartWeakPersistentValue::~DartWeakPersistentValue() {
-+  Clear();
-+}
-+
-+void DartWeakPersistentValue::Set(DartState* dart_state,
-+                                  Dart_Handle object,
-+                                  void* peer,
-+                                  intptr_t external_allocation_size,
-+                                  Dart_HandleFinalizer callback) {
-+  TONIC_DCHECK(is_empty());
-+  dart_state_ = dart_state->GetWeakPtr();
-+  handle_ = Dart_NewWeakPersistentHandle(object, peer, external_allocation_size,
-+                                         callback);
-+}
-+
-+void DartWeakPersistentValue::Clear() {
-+  if (!handle_) {
-+    return;
-+  }
-+
-+  auto dart_state = dart_state_.lock();
-+  if (!dart_state) {
-+    // The DartVM that the handle used to belong to has been shut down and that
-+    // handle has already been deleted.
-+    handle_ = nullptr;
-+    return;
-+  }
-+
-+  // The DartVM frees the handles during shutdown and calls the finalizers.
-+  // Freeing handles during shutdown would fail.
-+  if (!dart_state->IsShuttingDown()) {
-+    if (Dart_CurrentIsolateGroup()) {
-+      Dart_DeleteWeakPersistentHandle(handle_);
-+    } else {
-+      // If we are not on the mutator thread, this will fail. The caller must
-+      // ensure to be on the mutator thread.
-+      DartIsolateScope scope(dart_state->isolate());
-+      Dart_DeleteWeakPersistentHandle(handle_);
-+    }
-+  }
-+  // If it's shutting down, the handle will be deleted already.
-+
-+  dart_state_.reset();
-+  handle_ = nullptr;
-+}
-+
-+Dart_Handle DartWeakPersistentValue::Get() {
-+  auto dart_state = dart_state_.lock();
-+  TONIC_DCHECK(dart_state);
-+  TONIC_DCHECK(!dart_state->IsShuttingDown());
-+  if (!handle_) {
-+    return nullptr;
-+  }
-+  return Dart_HandleFromWeakPersistent(handle_);
-+}
-+
-+}  // namespace tonic
-diff --git a/third_party/tonic/dart_weak_persistent_value.h b/third_party/tonic/dart_weak_persistent_value.h
-new file mode 100644
-index 000000000..5f8aed5ee
---- /dev/null
-+++ b/third_party/tonic/dart_weak_persistent_value.h
-@@ -0,0 +1,48 @@
-+// Copyright 2013 The Flutter Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef LIB_TONIC_DART_WEAK_PERSISTENT_VALUE_H_
-+#define LIB_TONIC_DART_WEAK_PERSISTENT_VALUE_H_
-+
-+#include <memory>
-+
-+#include "third_party/dart/runtime/include/dart_api.h"
-+#include "tonic/common/macros.h"
-+
-+namespace tonic {
-+class DartState;
-+
-+// DartWeakPersistentValue is a bookkeeping class to help pair calls to
-+// Dart_NewWeakPersistentHandle with Dart_DeleteWeakPersistentHandle even in
-+// the case if IsolateGroup shutdown. Consider using this class instead of
-+// holding a Dart_PersistentHandle directly so that you don't leak the
-+// Dart_WeakPersistentHandle.
-+class DartWeakPersistentValue {
-+ public:
-+  DartWeakPersistentValue();
-+  ~DartWeakPersistentValue();
-+
-+  Dart_WeakPersistentHandle value() const { return handle_; }
-+  bool is_empty() const { return handle_ == nullptr; }
-+
-+  void Set(DartState* dart_state,
-+           Dart_Handle object,
-+           void* peer,
-+           intptr_t external_allocation_size,
-+           Dart_HandleFinalizer callback);
-+  void Clear();
-+  Dart_Handle Get();
-+
-+  const std::weak_ptr<DartState>& dart_state() const { return dart_state_; }
-+
-+ private:
-+  std::weak_ptr<DartState> dart_state_;
-+  Dart_WeakPersistentHandle handle_;
-+
-+  TONIC_DISALLOW_COPY_AND_ASSIGN(DartWeakPersistentValue);
-+};
-+
-+}  // namespace tonic
-+
-+#endif  // LIB_TONIC_DART_WEAK_PERSISTENT_VALUE_H_
-diff --git a/third_party/tonic/dart_wrappable.cc b/third_party/tonic/dart_wrappable.cc
-index 3bdfe3e6e..858215c11 100644
---- a/third_party/tonic/dart_wrappable.cc
-+++ b/third_party/tonic/dart_wrappable.cc
-@@ -12,12 +12,17 @@
- namespace tonic {
- 
- DartWrappable::~DartWrappable() {
--  TONIC_CHECK(!dart_wrapper_);
-+  // Calls the destructor of dart_wrapper_ to delete WeakPersistentHandle.
- }
- 
- // TODO(dnfield): Delete this. https://github.com/flutter/flutter/issues/50997
- Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
--  TONIC_DCHECK(!dart_wrapper_);
-+  if (!dart_wrapper_.is_empty()) {
-+    // Any previously given out wrapper must have been GCed.
-+    TONIC_DCHECK(Dart_IsNull(dart_wrapper_.Get()));
-+    dart_wrapper_.Clear();
-+  }
-+
-   const DartWrapperInfo& info = GetDartWrapperInfo();
- 
-   Dart_PersistentHandle type = dart_state->class_library().GetClass(info);
-@@ -36,14 +41,19 @@ Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
-   TONIC_DCHECK(!LogIfError(res));
- 
-   this->RetainDartWrappableReference();  // Balanced in FinalizeDartWrapper.
--  dart_wrapper_ = Dart_NewWeakPersistentHandle(
--      wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
-+  dart_wrapper_.Set(dart_state, wrapper, this, GetAllocationSize(),
-+                    &FinalizeDartWrapper);
- 
-   return wrapper;
- }
- 
- void DartWrappable::AssociateWithDartWrapper(Dart_Handle wrapper) {
--  TONIC_DCHECK(!dart_wrapper_);
-+  if (!dart_wrapper_.is_empty()) {
-+    // Any previously given out wrapper must have been GCed.
-+    TONIC_DCHECK(Dart_IsNull(dart_wrapper_.Get()));
-+    dart_wrapper_.Clear();
-+  }
-+
-   TONIC_CHECK(!LogIfError(wrapper));
- 
-   const DartWrapperInfo& info = GetDartWrapperInfo();
-@@ -54,26 +64,25 @@ void DartWrappable::AssociateWithDartWrapper(Dart_Handle wrapper) {
-       wrapper, kWrapperInfoIndex, reinterpret_cast<intptr_t>(&info))));
- 
-   this->RetainDartWrappableReference();  // Balanced in FinalizeDartWrapper.
--  dart_wrapper_ = Dart_NewWeakPersistentHandle(
--      wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
-+
-+  DartState* dart_state = DartState::Current();
-+  dart_wrapper_.Set(dart_state, wrapper, this, GetAllocationSize(),
-+                    &FinalizeDartWrapper);
- }
- 
- void DartWrappable::ClearDartWrapper() {
--  TONIC_DCHECK(dart_wrapper_);
--  Dart_Handle wrapper = Dart_HandleFromWeakPersistent(dart_wrapper_);
-+  TONIC_DCHECK(!dart_wrapper_.is_empty());
-+  Dart_Handle wrapper = dart_wrapper_.Get();
-   TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(wrapper, kPeerIndex, 0)));
-   TONIC_CHECK(
-       !LogIfError(Dart_SetNativeInstanceField(wrapper, kWrapperInfoIndex, 0)));
--  Dart_DeleteWeakPersistentHandle(dart_wrapper_);
--  dart_wrapper_ = nullptr;
-+  dart_wrapper_.Clear();
-   this->ReleaseDartWrappableReference();
- }
- 
- void DartWrappable::FinalizeDartWrapper(void* isolate_callback_data,
--                                        Dart_WeakPersistentHandle wrapper,
-                                         void* peer) {
-   DartWrappable* wrappable = reinterpret_cast<DartWrappable*>(peer);
--  wrappable->dart_wrapper_ = nullptr;
-   wrappable->ReleaseDartWrappableReference();  // Balanced in CreateDartWrapper.
- }
- 
-diff --git a/third_party/tonic/dart_wrappable.h b/third_party/tonic/dart_wrappable.h
-index a036abb85..f944dacef 100644
---- a/third_party/tonic/dart_wrappable.h
-+++ b/third_party/tonic/dart_wrappable.h
-@@ -9,6 +9,7 @@
- #include "tonic/common/macros.h"
- #include "tonic/converter/dart_converter.h"
- #include "tonic/dart_state.h"
-+#include "tonic/dart_weak_persistent_value.h"
- #include "tonic/dart_wrapper_info.h"
- #include "tonic/logging/dart_error.h"
- 
-@@ -26,7 +27,7 @@ class DartWrappable {
-     kNumberOfNativeFields,
-   };
- 
--  DartWrappable() : dart_wrapper_(nullptr) {}
-+  DartWrappable() : dart_wrapper_(DartWeakPersistentValue()) {}
- 
-   // Subclasses that wish to expose a new interface must override this function
-   // and provide information about their wrapper. There is no need to call your
-@@ -49,7 +50,9 @@ class DartWrappable {
-   Dart_Handle CreateDartWrapper(DartState* dart_state);
-   void AssociateWithDartWrapper(Dart_Handle wrappable);
-   void ClearDartWrapper();  // Warning: Might delete this.
--  Dart_WeakPersistentHandle dart_wrapper() const { return dart_wrapper_; }
-+  Dart_WeakPersistentHandle dart_wrapper() const {
-+    return dart_wrapper_.value();
-+  }
- 
-  protected:
-   virtual ~DartWrappable();
-@@ -59,11 +62,9 @@ class DartWrappable {
-       const tonic::DartWrapperInfo& wrapper_info);
- 
-  private:
--  static void FinalizeDartWrapper(void* isolate_callback_data,
--                                  Dart_WeakPersistentHandle wrapper,
--                                  void* peer);
-+  static void FinalizeDartWrapper(void* isolate_callback_data, void* peer);
- 
--  Dart_WeakPersistentHandle dart_wrapper_;
-+  DartWeakPersistentValue dart_wrapper_;
- 
-   TONIC_DISALLOW_COPY_AND_ASSIGN(DartWrappable);
- };
-@@ -103,22 +104,36 @@ struct DartConverter<
-     typename std::enable_if<
-         std::is_convertible<T*, const DartWrappable*>::value>::type> {
-   static Dart_Handle ToDart(DartWrappable* val) {
--    if (!val)
-+    if (!val) {
-       return Dart_Null();
--    if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper())
--      return Dart_HandleFromWeakPersistent(wrapper);
-+    }
-+    if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper()) {
-+      auto strong_handle = Dart_HandleFromWeakPersistent(wrapper);
-+      if (!Dart_IsNull(strong_handle)) {
-+        return strong_handle;
-+      }
-+      // After the weak referenced object has been GCed, the handle points to
-+      // Dart_Null(). Fall through create a new wrapper object.
-+    }
-     return val->CreateDartWrapper(DartState::Current());
-   }
- 
-   static void SetReturnValue(Dart_NativeArguments args,
-                              DartWrappable* val,
-                              bool auto_scope = true) {
--    if (!val)
-+    if (!val) {
-       Dart_SetReturnValue(args, Dart_Null());
--    else if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper())
--      Dart_SetWeakHandleReturnValue(args, wrapper);
--    else
--      Dart_SetReturnValue(args, val->CreateDartWrapper(DartState::Current()));
-+      return;
-+    } else if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper()) {
-+      auto strong_handle = Dart_HandleFromWeakPersistent(wrapper);
-+      if (!Dart_IsNull(strong_handle)) {
-+        Dart_SetReturnValue(args, strong_handle);
-+        return;
-+      }
-+      // After the weak referenced object has been GCed, the handle points to
-+      // Dart_Null(). Fall through create a new wrapper object.
-+    }
-+    Dart_SetReturnValue(args, val->CreateDartWrapper(DartState::Current()));
-   }
- 
-   static T* FromDart(Dart_Handle handle) {
-diff --git a/third_party/tonic/tests/BUILD.gn b/third_party/tonic/tests/BUILD.gn
-new file mode 100644
-index 000000000..359deb13b
---- /dev/null
-+++ b/third_party/tonic/tests/BUILD.gn
-@@ -0,0 +1,33 @@
-+# Copyright 2013 The Flutter Authors. All rights reserved.
-+# Use of this source code is governed by a BSD-style license that can be
-+# found in the LICENSE file.
-+
-+import("//flutter/testing/testing.gni")
-+
-+test_fixtures("tonic_fixtures") {
-+  dart_main = "fixtures/tonic_test.dart"
-+  fixtures = []
-+}
-+
-+executable("tonic_unittests") {
-+  testonly = true
-+
-+  public_configs = [ "//flutter:export_dynamic_symbols" ]
-+
-+  sources = [
-+    "dart_state_unittest.cc",
-+    "dart_weak_persistent_handle_unittest.cc",
-+  ]
-+
-+  public_deps = [
-+    ":tonic_fixtures",
-+    "//flutter/runtime:libdart",
-+    "//flutter/runtime:runtime",
-+    "//flutter/testing",
-+    "//flutter/testing:fixture_test",
-+    "//third_party/dart/runtime:dart_api",
-+    "//third_party/googletest:gtest",
-+  ]
-+
-+  deps = [ "../:tonic" ]
-+}
-diff --git a/third_party/tonic/tests/dart_state_unittest.cc b/third_party/tonic/tests/dart_state_unittest.cc
-new file mode 100644
-index 000000000..3d053de40
---- /dev/null
-+++ b/third_party/tonic/tests/dart_state_unittest.cc
-@@ -0,0 +1,61 @@
-+// Copyright 2013 The Flutter Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "flutter/common/task_runners.h"
-+#include "flutter/runtime/dart_vm_lifecycle.h"
-+#include "flutter/runtime/isolate_configuration.h"
-+#include "flutter/testing/fixture_test.h"
-+
-+namespace flutter {
-+namespace testing {
-+
-+using DartState = FixtureTest;
-+
-+TEST_F(DartState, IsShuttingDown) {
-+  ASSERT_FALSE(DartVMRef::IsInstanceRunning());
-+  auto settings = CreateSettingsForFixture();
-+  auto vm_ref = DartVMRef::Create(settings);
-+  ASSERT_TRUE(vm_ref);
-+  auto vm_data = vm_ref.GetVMData();
-+  ASSERT_TRUE(vm_data);
-+  TaskRunners task_runners(GetCurrentTestName(),    //
-+                           GetCurrentTaskRunner(),  //
-+                           GetCurrentTaskRunner(),  //
-+                           GetCurrentTaskRunner(),  //
-+                           GetCurrentTaskRunner()   //
-+  );
-+  auto isolate_configuration =
-+      IsolateConfiguration::InferFromSettings(settings);
-+  auto weak_isolate = DartIsolate::CreateRunningRootIsolate(
-+      vm_data->GetSettings(),              // settings
-+      vm_data->GetIsolateSnapshot(),       // isolate snapshot
-+      std::move(task_runners),             // task runners
-+      nullptr,                             // window
-+      {},                                  // snapshot delegate
-+      {},                                  // hint freed delegate
-+      {},                                  // io manager
-+      {},                                  // unref queue
-+      {},                                  // image decoder
-+      "main.dart",                         // advisory uri
-+      "main",                              // advisory entrypoint
-+      DartIsolate::Flags{},                // flags
-+      settings.isolate_create_callback,    // isolate create callback
-+      settings.isolate_shutdown_callback,  // isolate shutdown callback
-+      "main",                              // dart entrypoint
-+      std::nullopt,                        // dart entrypoint library
-+      std::move(isolate_configuration)     // isolate configuration
-+  );
-+  auto root_isolate = weak_isolate.lock();
-+  ASSERT_TRUE(root_isolate);
-+
-+  tonic::DartState* dart_state = root_isolate.get();
-+  ASSERT_FALSE(dart_state->IsShuttingDown());
-+
-+  ASSERT_TRUE(root_isolate->Shutdown());
-+
-+  ASSERT_TRUE(dart_state->IsShuttingDown());
-+}
-+
-+}  // namespace testing
-+}  // namespace flutter
-diff --git a/third_party/tonic/tests/dart_weak_persistent_handle_unittest.cc b/third_party/tonic/tests/dart_weak_persistent_handle_unittest.cc
-new file mode 100644
-index 000000000..65d5e116c
---- /dev/null
-+++ b/third_party/tonic/tests/dart_weak_persistent_handle_unittest.cc
-@@ -0,0 +1,167 @@
-+// Copyright 2013 The Flutter Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "flutter/testing/dart_isolate_runner.h"
-+#include "flutter/testing/fixture_test.h"
-+
-+namespace flutter {
-+namespace testing {
-+
-+class DartWeakPersistentHandle : public FixtureTest {
-+ public:
-+  DartWeakPersistentHandle()
-+      : settings_(CreateSettingsForFixture()),
-+        vm_(DartVMRef::Create(settings_)) {}
-+
-+  ~DartWeakPersistentHandle() = default;
-+
-+  [[nodiscard]] bool RunWithEntrypoint(const std::string& entrypoint) {
-+    if (running_isolate_) {
-+      return false;
-+    }
-+    auto thread = CreateNewThread();
-+    TaskRunners single_threaded_task_runner(GetCurrentTestName(), thread,
-+                                            thread, thread, thread);
-+    auto isolate =
-+        RunDartCodeInIsolate(vm_, settings_, single_threaded_task_runner,
-+                             entrypoint, {}, GetFixturesPath());
-+    if (!isolate || isolate->get()->GetPhase() != DartIsolate::Phase::Running) {
-+      return false;
-+    }
-+
-+    running_isolate_ = std::move(isolate);
-+    return true;
-+  }
-+
-+  [[nodiscard]] bool RunInIsolateScope(std::function<bool(void)> closure) {
-+    return running_isolate_->RunInIsolateScope(closure);
-+  }
-+
-+ private:
-+  Settings settings_;
-+  DartVMRef vm_;
-+  std::unique_ptr<AutoIsolateShutdown> running_isolate_;
-+  FML_DISALLOW_COPY_AND_ASSIGN(DartWeakPersistentHandle);
-+};
-+
-+void NopFinalizer(void* isolate_callback_data, void* peer) {}
-+
-+TEST_F(DartWeakPersistentHandle, ClearImmediately) {
-+  auto weak_persistent_value = tonic::DartWeakPersistentValue();
-+
-+  fml::AutoResetWaitableEvent event;
-+
-+  AddNativeCallback(
-+      "GiveObjectToNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
-+        auto handle = Dart_GetNativeArgument(args, 0);
-+
-+        auto dart_state = tonic::DartState::Current();
-+        ASSERT_TRUE(dart_state);
-+        ASSERT_TRUE(tonic::DartState::Current());
-+        weak_persistent_value.Set(dart_state, handle, nullptr, 0, NopFinalizer);
-+
-+        weak_persistent_value.Clear();
-+
-+        event.Signal();
-+      }));
-+
-+  ASSERT_TRUE(RunWithEntrypoint("callGiveObjectToNative"));
-+
-+  event.Wait();
-+}
-+
-+TEST_F(DartWeakPersistentHandle, ClearLaterCc) {
-+  auto weak_persistent_value = tonic::DartWeakPersistentValue();
-+
-+  fml::AutoResetWaitableEvent event;
-+
-+  AddNativeCallback(
-+      "GiveObjectToNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
-+        auto handle = Dart_GetNativeArgument(args, 0);
-+
-+        auto dart_state = tonic::DartState::Current();
-+        ASSERT_TRUE(dart_state);
-+        ASSERT_TRUE(tonic::DartState::Current());
-+        weak_persistent_value.Set(dart_state, handle, nullptr, 0, NopFinalizer);
-+
-+        // Do not clear handle immediately.
-+
-+        event.Signal();
-+      }));
-+
-+  ASSERT_TRUE(RunWithEntrypoint("callGiveObjectToNative"));
-+
-+  event.Wait();
-+
-+  ASSERT_TRUE(RunInIsolateScope([&weak_persistent_value]() -> bool {
-+    // Clear on initiative of native.
-+    weak_persistent_value.Clear();
-+    return true;
-+  }));
-+}
-+
-+TEST_F(DartWeakPersistentHandle, ClearLaterDart) {
-+  auto weak_persistent_value = tonic::DartWeakPersistentValue();
-+
-+  fml::AutoResetWaitableEvent event;
-+
-+  AddNativeCallback(
-+      "GiveObjectToNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
-+        auto handle = Dart_GetNativeArgument(args, 0);
-+
-+        auto dart_state = tonic::DartState::Current();
-+        ASSERT_TRUE(dart_state);
-+        ASSERT_TRUE(tonic::DartState::Current());
-+        weak_persistent_value.Set(dart_state, handle, nullptr, 0, NopFinalizer);
-+
-+        // Do not clear handle immediately.
-+      }));
-+
-+  AddNativeCallback("SignalDone",
-+                    CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
-+                      // Clear on initiative of Dart.
-+                      weak_persistent_value.Clear();
-+
-+                      event.Signal();
-+                    }));
-+
-+  ASSERT_TRUE(RunWithEntrypoint("testClearLater"));
-+
-+  event.Wait();
-+}
-+
-+// Handle outside the test body scope so it survives until isolate shutdown.
-+tonic::DartWeakPersistentValue global_weak_persistent_value =
-+    tonic::DartWeakPersistentValue();
-+
-+TEST_F(DartWeakPersistentHandle, ClearOnShutdown) {
-+  fml::AutoResetWaitableEvent event;
-+
-+  AddNativeCallback("GiveObjectToNative",
-+                    CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
-+                      auto handle = Dart_GetNativeArgument(args, 0);
-+
-+                      auto dart_state = tonic::DartState::Current();
-+                      ASSERT_TRUE(dart_state);
-+                      ASSERT_TRUE(tonic::DartState::Current());
-+
-+                      // The test is repeated, ensure the global var is
-+                      // cleared before use.
-+                      global_weak_persistent_value.Clear();
-+
-+                      global_weak_persistent_value.Set(
-+                          dart_state, handle, nullptr, 0, NopFinalizer);
-+
-+                      // Do not clear handle, so it is cleared on shutdown.
-+
-+                      event.Signal();
-+                    }));
-+
-+  ASSERT_TRUE(RunWithEntrypoint("callGiveObjectToNative"));
-+
-+  event.Wait();
-+}
-+
-+}  // namespace testing
-+}  // namespace flutter
-diff --git a/third_party/tonic/tests/fixtures/tonic_test.dart b/third_party/tonic/tests/fixtures/tonic_test.dart
-new file mode 100644
-index 000000000..83e92d4dc
---- /dev/null
-+++ b/third_party/tonic/tests/fixtures/tonic_test.dart
-@@ -0,0 +1,25 @@
-+// Copyright 2013 The Flutter Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+void main() {}
-+
-+class SomeClass {
-+  int i;
-+  SomeClass(this.i);
-+}
-+
-+void giveObjectToNative(Object someObject) native 'GiveObjectToNative';
-+
-+void signalDone() native 'SignalDone';
-+
-+@pragma('vm:entry-point')
-+void callGiveObjectToNative() {
-+  giveObjectToNative(SomeClass(123));
-+}
-+
-+@pragma('vm:entry-point')
-+void testClearLater() {
-+  giveObjectToNative(SomeClass(123));
-+  signalDone();
-+}
-diff --git a/third_party/tonic/typed_data/dart_byte_data.cc b/third_party/tonic/typed_data/dart_byte_data.cc
-index dc312de3f..cfb07399f 100644
---- a/third_party/tonic/typed_data/dart_byte_data.cc
-+++ b/third_party/tonic/typed_data/dart_byte_data.cc
-@@ -16,9 +16,7 @@ namespace {
- // with a buffer allocated outside the Dart heap.
- const int kExternalSizeThreshold = 1000;
- 
--void FreeFinalizer(void* isolate_callback_data,
--                   Dart_WeakPersistentHandle handle,
--                   void* peer) {
-+void FreeFinalizer(void* isolate_callback_data, void* peer) {
-   free(peer);
- }
-