Version 2.10.0-126.0.dev

Merge commit '2f1ad1e92910a598b5c97528f13f516de76bb653' into 'dev'
diff --git a/build/rust/rust.gni b/build/rust/rust.gni
index c3fb4dc..0a8cdc1 100644
--- a/build/rust/rust.gni
+++ b/build/rust/rust.gni
@@ -74,7 +74,7 @@
   } else {
     if (is_win) {
       output_file = "${invoker.lib_name}.lib"
-    }else {
+    } else {
       output_file = "lib${invoker.lib_name}.a"
     }
   }
@@ -89,7 +89,7 @@
   config("${target_name}_cargo_config") {
     if (!shared) {
       libs = [ invoker.lib_name ]
-      lib_dirs = [ out_dir ]
+      lib_dirs = [ target_out_dir ]
     }
   }
 
@@ -97,7 +97,7 @@
   # So we need to copy it to target_out_dir to make it easier for dependees to
   # locate the library.
   copy(target_name) {
-    deps = [ ":${target_name}_cargo" ]
+    public_deps = [ ":${target_name}_cargo" ]
     sources = [ "${cargo_out_dir}/${output_file}" ]
     outputs = [ "${target_out_dir}/${output_file}" ]
   }
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index af7ea7b..4f13b90 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -536,6 +536,7 @@
   HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER,
   HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT,
   HintCode.RECEIVER_OF_TYPE_NEVER,
+  HintCode.RETURN_OF_DO_NOT_STORE,
   HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE,
   HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 7aef562..9d9c4eb 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -1555,6 +1555,16 @@
           "receiver");
 
   /**
+   * Users should not return values marked `@doNotStore` from functions,
+   * methods or getters not marked `@doNotStore`.
+   */
+  static const HintCode RETURN_OF_DO_NOT_STORE = HintCode(
+      'RETURN_OF_DO_NOT_STORE',
+      "'{0}' is annotated with 'doNotStore' and shouldn't be returned unless "
+          "'{1}' is also annotated.",
+      correction: "Annotate '{1}' with 'doNotStore'.");
+
+  /**
    * No parameters.
    */
   // #### Description
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 8cfc83d..8809534 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -323,6 +323,12 @@
   }
 
   @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _checkForReturnOfDoNotStore(node.expression);
+    super.visitExpressionFunctionBody(node);
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     bool wasInDeprecatedMember = _inDeprecatedMember;
     if (_hasDeprecatedAnnotation(node.metadata)) {
@@ -363,22 +369,7 @@
 
         var expression = field.initializer;
 
-        Element element;
-        if (expression is PropertyAccess) {
-          element = expression.propertyName.staticElement;
-          // Tear-off.
-          if (element is FunctionElement || element is MethodElement) {
-            element = null;
-          }
-        } else if (expression is MethodInvocation) {
-          element = expression.methodName.staticElement;
-        } else if (expression is Identifier) {
-          element = expression.staticElement;
-          // Tear-off.
-          if (element is FunctionElement || element is MethodElement) {
-            element = null;
-          }
-        }
+        var element = _getElement(expression);
         if (element != null) {
           if (element is PropertyAccessorElement && element.isSynthetic) {
             element = (element as PropertyAccessorElement).variable;
@@ -626,6 +617,12 @@
   }
 
   @override
+  void visitReturnStatement(ReturnStatement node) {
+    _checkForReturnOfDoNotStore(node.expression);
+    super.visitReturnStatement(node);
+  }
+
+  @override
   void visitSetOrMapLiteral(SetOrMapLiteral node) {
     _checkForDuplications(node);
     super.visitSetOrMapLiteral(node);
@@ -1298,6 +1295,21 @@
     }
   }
 
+  void _checkForReturnOfDoNotStore(Expression expression) {
+    var element = _getElement(expression);
+    if (element != null && element.hasOrInheritsDoNotStore) {
+      var parent = expression.thisOrAncestorMatching(
+          (e) => e is FunctionDeclaration || e is MethodDeclaration);
+      if (parent is Declaration && !parent.declaredElement.hasDoNotStore) {
+        _errorReporter.reportErrorForNode(
+          HintCode.RETURN_OF_DO_NOT_STORE,
+          expression,
+          [element.name, parent.declaredElement.displayName],
+        );
+      }
+    }
+  }
+
   /// Generate a hint for `noSuchMethod` methods that do nothing except of
   /// calling another `noSuchMethod` that is not defined by `Object`.
   ///
@@ -1441,6 +1453,31 @@
     }
   }
 
+  Element _getElement(Expression expression) {
+    Element element;
+    if (expression is PropertyAccess) {
+      element = expression.propertyName.staticElement;
+      // Tear-off.
+      if (element is FunctionElement || element is MethodElement) {
+        element = null;
+      }
+    } else if (expression is MethodInvocation) {
+      element = expression.methodName.staticElement;
+    } else if (expression is Identifier) {
+      element = expression.staticElement;
+      // Tear-off.
+      if (element is FunctionElement || element is MethodElement) {
+        element = null;
+      }
+    }
+    if (element != null) {
+      if (element is PropertyAccessorElement && element.isSynthetic) {
+        element = (element as PropertyAccessorElement).variable;
+      }
+    }
+    return element;
+  }
+
   bool _isLibraryInWorkspacePackage(LibraryElement library) {
     if (_workspacePackage == null || library == null) {
       // Better to not make a big claim that they _are_ in the same package,
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_do_not_store_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_do_not_store_test.dart
new file mode 100644
index 0000000..51c1819
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/return_of_do_not_store_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReturnOfDoNotStoreTest);
+  });
+}
+
+@reflectiveTest
+class ReturnOfDoNotStoreTest extends PubPackageResolutionTest {
+  @override
+  void setUp() {
+    super.setUp();
+    writeTestPackageConfigWithMeta();
+  }
+
+  test_returnFromFunction() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+@doNotStore
+String v = '';
+
+String getV() {
+  return v;
+}
+
+String getV2() => v;
+
+@doNotStore
+String getV3() => v;
+''', [
+      error(HintCode.RETURN_OF_DO_NOT_STORE, 87, 1, messageContains: 'getV'),
+      error(HintCode.RETURN_OF_DO_NOT_STORE, 111, 1, messageContains: 'getV2'),
+    ]);
+  }
+
+  test_returnFromGetter() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+@doNotStore
+String _v = '';
+
+String get v {
+  return _v;
+}
+
+String get v2 => _v;
+
+@doNotStore
+String get v3 => _v;
+''', [
+      error(HintCode.RETURN_OF_DO_NOT_STORE, 87, 2, messageContains: 'v'),
+      error(HintCode.RETURN_OF_DO_NOT_STORE, 111, 2, messageContains: 'v2'),
+    ]);
+  }
+
+  test_returnFromMethod() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+
+class A {
+  @doNotStore
+  String _v = '';
+
+  String getV() {
+    return _v;
+  }
+
+  String getV2() => _v;
+  
+  @doNotStore
+  String getV3() => _v;
+}
+''', [
+      error(HintCode.RETURN_OF_DO_NOT_STORE, 106, 2, messageContains: 'getV'),
+      error(HintCode.RETURN_OF_DO_NOT_STORE, 135, 2, messageContains: 'getV2'),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 57f747d..55f08d2 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -519,6 +519,7 @@
 import 'return_in_generative_constructor_test.dart'
     as return_in_generative_constructor;
 import 'return_in_generator_test.dart' as return_in_generator;
+import 'return_of_do_not_store_test.dart' as return_of_do_not_store;
 import 'return_of_invalid_type_test.dart' as return_of_invalid_type;
 import 'return_without_value_test.dart' as return_without_value;
 import 'sdk_version_as_expression_in_const_context_test.dart'
@@ -984,6 +985,7 @@
     rethrow_outside_catch.main();
     return_in_generative_constructor.main();
     return_in_generator.main();
+    return_of_do_not_store.main();
     return_of_invalid_type.main();
     return_without_value.main();
     set_element_from_deferred_library.main();
diff --git a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
index bf77587..50317ba 100644
--- a/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/info_builder.dart
@@ -313,6 +313,17 @@
     var content = result.content;
     unitInfo.diskContent = content;
     var regions = unitInfo.regions;
+
+    // There are certain rare conditions involving generated code in a bazel
+    // workspace that can cause a source file to get processed more than once by
+    // the migration tool (sometimes with a correct URI, sometimes with an
+    // incorrect URI that corresponds to a file path in the `bazel-out`
+    // directory).  That can cause this method to get called twice for the same
+    // unit.  To avoid this creating user-visible problems, we need to ensure
+    // that any regions left over from the previous invocation are cleared out
+    // before we re-populate the region list.
+    regions.clear();
+
     var lineInfo = result.unit.lineInfo;
     var insertions = <int, List<AtomicEdit>>{};
     var hintsSeen = <HintComment>{};
diff --git a/pkg/wasm/lib/src/module.dart b/pkg/wasm/lib/src/module.dart
index 1034a9e..c227eb4 100644
--- a/pkg/wasm/lib/src/module.dart
+++ b/pkg/wasm/lib/src/module.dart
@@ -22,6 +22,24 @@
   WasmInstance instantiate(WasmImports imports) {
     return WasmInstance(_module, imports);
   }
+
+  /// Returns a description of all of the module's imports and exports, for
+  /// debugging.
+  String describe() {
+    var description = StringBuffer();
+    var runtime = WasmRuntime();
+    var imports = runtime.importDescriptors(_module);
+    for (var imp in imports) {
+      var kind = wasmerImpExpKindName(imp.kind);
+      description.write('import $kind: ${imp.moduleName}::${imp.name}\n');
+    }
+    var exports = runtime.exportDescriptors(_module);
+    for (var exp in exports) {
+      var kind = wasmerImpExpKindName(exp.kind);
+      description.write('export $kind: ${exp.name}\n');
+    }
+    return description.toString();
+  }
 }
 
 /// WasmImports holds all the imports for a WasmInstance.
@@ -43,22 +61,25 @@
 class WasmInstance {
   Pointer<WasmerModule> _module;
   Pointer<WasmerInstance> _instance;
-  List<WasmFunction> _functions;
+  Map<String, WasmFunction> _functions;
 
   WasmInstance(this._module, WasmImports imports) {
     var runtime = WasmRuntime();
     _instance = runtime.instantiate(_module, imports._imports, imports.length);
-    _functions = [];
+    _functions = {};
     var exps = runtime.exports(_instance);
     for (var e in exps) {
       var kind = runtime.exportKind(e);
+      String name = runtime.exportName(e);
       if (kind == WasmerImpExpKindFunction) {
         var f = runtime.exportToFunction(e);
-        _functions.add(
-            WasmFunction(f, runtime.getArgTypes(f), runtime.getReturnType(f)));
+        _functions[name] =
+            WasmFunction(f, runtime.getArgTypes(f), runtime.getReturnType(f));
       }
     }
   }
 
-  List<dynamic> get functions => _functions;
+  dynamic lookupFunction(String name) {
+    return _functions[name];
+  }
 }
diff --git a/pkg/wasm/lib/src/runtime.dart b/pkg/wasm/lib/src/runtime.dart
index b8d3686..304b9fe 100644
--- a/pkg/wasm/lib/src/runtime.dart
+++ b/pkg/wasm/lib/src/runtime.dart
@@ -10,6 +10,19 @@
 import 'package:path/path.dart' as path;
 import 'wasmer_api.dart';
 
+class WasmImportDescriptor {
+  int kind;
+  String moduleName;
+  String name;
+  WasmImportDescriptor(this.kind, this.moduleName, this.name);
+}
+
+class WasmExportDescriptor {
+  int kind;
+  String name;
+  WasmExportDescriptor(this.kind, this.name);
+}
+
 class WasmRuntime {
   static WasmRuntime _inst;
 
@@ -26,6 +39,20 @@
   WasmerExportFuncParamsArityFn _export_func_params_arity;
   WasmerExportFuncParamsFn _export_func_params;
   WasmerExportFuncCallFn _export_func_call;
+  WasmerExportNamePtrFn _export_name_ptr;
+  WasmerExportDescriptorsFn _export_descriptors;
+  WasmerExportDescriptorsDestroyFn _export_descriptors_destroy;
+  WasmerExportDescriptorsLenFn _export_descriptors_len;
+  WasmerExportDescriptorsGetFn _export_descriptors_get;
+  WasmerExportDescriptorKindFn _export_descriptor_kind;
+  WasmerExportDescriptorNamePtrFn _export_descriptor_name_ptr;
+  WasmerImportDescriptorModuleNamePtrFn _import_descriptor_module_name_ptr;
+  WasmerImportDescriptorNamePtrFn _import_descriptor_name_ptr;
+  WasmerImportDescriptorsFn _import_descriptors;
+  WasmerImportDescriptorsDestroyFn _import_descriptors_destroy;
+  WasmerImportDescriptorsLenFn _import_descriptors_len;
+  WasmerImportDescriptorsGetFn _import_descriptors_get;
+  WasmerImportDescriptorKindFn _import_descriptor_kind;
 
   factory WasmRuntime() {
     if (_inst == null) {
@@ -35,8 +62,8 @@
   }
 
   static String _getLibName() {
-    if (Platform.isMacOS) return "libwasmer.dylib";
-    if (Platform.isLinux) return "libwasmer.so";
+    if (Platform.isMacOS) return "libwasmer_wrapper.dylib";
+    if (Platform.isLinux) return "libwasmer_wrapper.so";
     throw Exception("Wasm not currently supported on this platform");
   }
 
@@ -103,6 +130,47 @@
         WasmerExportFuncParamsFn>('wasmer_export_func_params');
     _export_func_call = _lib.lookupFunction<NativeWasmerExportFuncCallFn,
         WasmerExportFuncCallFn>('wasmer_export_func_call');
+    _export_descriptors = _lib.lookupFunction<NativeWasmerExportDescriptorsFn,
+        WasmerExportDescriptorsFn>('wasmer_export_descriptors');
+    _export_descriptors_destroy = _lib.lookupFunction<
+        NativeWasmerExportDescriptorsDestroyFn,
+        WasmerExportDescriptorsDestroyFn>('wasmer_export_descriptors_destroy');
+    _export_descriptors_len = _lib.lookupFunction<
+        NativeWasmerExportDescriptorsLenFn,
+        WasmerExportDescriptorsLenFn>('wasmer_export_descriptors_len');
+    _export_descriptors_get = _lib.lookupFunction<
+        NativeWasmerExportDescriptorsGetFn,
+        WasmerExportDescriptorsGetFn>('wasmer_export_descriptors_get');
+    _export_descriptor_kind = _lib.lookupFunction<
+        NativeWasmerExportDescriptorKindFn,
+        WasmerExportDescriptorKindFn>('wasmer_export_descriptor_kind');
+    _export_name_ptr =
+        _lib.lookupFunction<NativeWasmerExportNamePtrFn, WasmerExportNamePtrFn>(
+            'wasmer_export_name_ptr');
+    _export_descriptor_name_ptr = _lib.lookupFunction<
+        NativeWasmerExportDescriptorNamePtrFn,
+        WasmerExportDescriptorNamePtrFn>('wasmer_export_descriptor_name_ptr');
+    _import_descriptors = _lib.lookupFunction<NativeWasmerImportDescriptorsFn,
+        WasmerImportDescriptorsFn>('wasmer_import_descriptors');
+    _import_descriptors_destroy = _lib.lookupFunction<
+        NativeWasmerImportDescriptorsDestroyFn,
+        WasmerImportDescriptorsDestroyFn>('wasmer_import_descriptors_destroy');
+    _import_descriptors_len = _lib.lookupFunction<
+        NativeWasmerImportDescriptorsLenFn,
+        WasmerImportDescriptorsLenFn>('wasmer_import_descriptors_len');
+    _import_descriptors_get = _lib.lookupFunction<
+        NativeWasmerImportDescriptorsGetFn,
+        WasmerImportDescriptorsGetFn>('wasmer_import_descriptors_get');
+    _import_descriptor_kind = _lib.lookupFunction<
+        NativeWasmerImportDescriptorKindFn,
+        WasmerImportDescriptorKindFn>('wasmer_import_descriptor_kind');
+    _import_descriptor_module_name_ptr = _lib.lookupFunction<
+            NativeWasmerImportDescriptorModuleNamePtrFn,
+            WasmerImportDescriptorModuleNamePtrFn>(
+        'wasmer_import_descriptor_module_name_ptr');
+    _import_descriptor_name_ptr = _lib.lookupFunction<
+        NativeWasmerImportDescriptorNamePtrFn,
+        WasmerImportDescriptorNamePtrFn>('wasmer_import_descriptor_name_ptr');
   }
 
   Pointer<WasmerModule> compile(Uint8List data) {
@@ -125,6 +193,49 @@
     return modulePtr;
   }
 
+  String _callStringWrapperFunction(Function fn, dynamic arg) {
+    var strPtr = allocate<WasmerByteArray>();
+    fn(arg, strPtr);
+    var str = strPtr.ref.string;
+    free(strPtr);
+    return str;
+  }
+
+  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
+    var exportsPtrPtr = allocate<Pointer<WasmerExportDescriptors>>();
+    _export_descriptors(module, exportsPtrPtr);
+    Pointer<WasmerExportDescriptors> exportsPtr = exportsPtrPtr.value;
+    free(exportsPtrPtr);
+    var n = _export_descriptors_len(exportsPtr);
+    var exps = <WasmExportDescriptor>[];
+    for (var i = 0; i < n; ++i) {
+      var exp = _export_descriptors_get(exportsPtr, i);
+      exps.add(WasmExportDescriptor(_export_descriptor_kind(exp),
+          _callStringWrapperFunction(_export_descriptor_name_ptr, exp)));
+    }
+    _export_descriptors_destroy(exportsPtr);
+    return exps;
+  }
+
+  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
+    var importsPtrPtr = allocate<Pointer<WasmerImportDescriptors>>();
+    _import_descriptors(module, importsPtrPtr);
+    Pointer<WasmerImportDescriptors> importsPtr = importsPtrPtr.value;
+    free(importsPtrPtr);
+
+    var n = _import_descriptors_len(importsPtr);
+    var imps = <WasmImportDescriptor>[];
+    for (var i = 0; i < n; ++i) {
+      var imp = _import_descriptors_get(importsPtr, i);
+      imps.add(WasmImportDescriptor(
+          _import_descriptor_kind(imp),
+          _callStringWrapperFunction(_import_descriptor_module_name_ptr, imp),
+          _callStringWrapperFunction(_import_descriptor_name_ptr, imp)));
+    }
+    _import_descriptors_destroy(importsPtr);
+    return imps;
+  }
+
   Pointer<WasmerInstance> instantiate(Pointer<WasmerModule> module,
       Pointer<WasmerImport> imports, int numImports) {
     var instancePtrPtr = allocate<Pointer<WasmerInstance>>();
@@ -157,6 +268,10 @@
     return _export_kind(export);
   }
 
+  String exportName(Pointer<WasmerExport> export) {
+    return _callStringWrapperFunction(_export_name_ptr, export);
+  }
+
   Pointer<WasmerExportFunc> exportToFunction(Pointer<WasmerExport> export) {
     return _export_to_func(export);
   }
diff --git a/pkg/wasm/lib/src/wasmer_api.dart b/pkg/wasm/lib/src/wasmer_api.dart
index dc5df74..2f54b53 100644
--- a/pkg/wasm/lib/src/wasmer_api.dart
+++ b/pkg/wasm/lib/src/wasmer_api.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:convert';
 import 'dart:ffi';
 import 'dart:typed_data';
 
@@ -24,6 +25,21 @@
 const int WasmerImpExpKindMemory = 2;
 const int WasmerImpExpKindTable = 3;
 
+String wasmerImpExpKindName(int kind) {
+  switch (kind) {
+    case WasmerImpExpKindFunction:
+      return "function";
+    case WasmerImpExpKindGlobal:
+      return "global";
+    case WasmerImpExpKindMemory:
+      return "memory";
+    case WasmerImpExpKindTable:
+      return "table";
+    default:
+      return "unknown";
+  }
+}
+
 // wasmer_module_t
 class WasmerModule extends Struct {}
 
@@ -36,9 +52,21 @@
 // wasmer_export_t
 class WasmerExport extends Struct {}
 
+// wasmer_export_descriptors_t
+class WasmerExportDescriptors extends Struct {}
+
+// wasmer_export_descriptor_t
+class WasmerExportDescriptor extends Struct {}
+
 // wasmer_export_func_t
 class WasmerExportFunc extends Struct {}
 
+// wasmer_import_descriptors_t
+class WasmerImportDescriptors extends Struct {}
+
+// wasmer_import_descriptor_t
+class WasmerImportDescriptor extends Struct {}
+
 // wasmer_import_t
 class WasmerImport extends Struct {
   Pointer<Uint8> module_name;
@@ -69,6 +97,7 @@
   int length;
 
   Uint8List get list => bytes.asTypedList(length);
+  String get string => utf8.decode(list);
 }
 
 // wasmer_value_t
@@ -130,10 +159,89 @@
 typedef WasmerExportsGetFn = Pointer<WasmerExport> Function(
     Pointer<WasmerExports>, int);
 
-// wasmer_export_name
-typedef NativeWasmerExportNameFn = WasmerByteArray Function(
-    Pointer<WasmerExport>);
-typedef WasmerExportNameFn = WasmerByteArray Function(Pointer<WasmerExport>);
+// wasmer_export_descriptors
+typedef NativeWasmerExportDescriptorsFn = Void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerExportDescriptors>>);
+typedef WasmerExportDescriptorsFn = void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerExportDescriptors>>);
+
+// wasmer_export_descriptors_destroy
+typedef NativeWasmerExportDescriptorsDestroyFn = Void Function(
+    Pointer<WasmerExportDescriptors>);
+typedef WasmerExportDescriptorsDestroyFn = void Function(
+    Pointer<WasmerExportDescriptors>);
+
+// wasmer_export_descriptors_len
+typedef NativeWasmerExportDescriptorsLenFn = Int32 Function(
+    Pointer<WasmerExportDescriptors>);
+typedef WasmerExportDescriptorsLenFn = int Function(
+    Pointer<WasmerExportDescriptors>);
+
+// wasmer_export_descriptors_get
+typedef NativeWasmerExportDescriptorsGetFn = Pointer<WasmerExportDescriptor>
+    Function(Pointer<WasmerExportDescriptors>, Int32);
+typedef WasmerExportDescriptorsGetFn = Pointer<WasmerExportDescriptor> Function(
+    Pointer<WasmerExportDescriptors>, int);
+
+// wasmer_export_descriptor_kind
+typedef NativeWasmerExportDescriptorKindFn = Uint32 Function(
+    Pointer<WasmerExportDescriptor>);
+typedef WasmerExportDescriptorKindFn = int Function(
+    Pointer<WasmerExportDescriptor>);
+
+// wasmer_export_descriptor_name_ptr
+typedef NativeWasmerExportDescriptorNamePtrFn = Void Function(
+    Pointer<WasmerExportDescriptor>, Pointer<WasmerByteArray>);
+typedef WasmerExportDescriptorNamePtrFn = void Function(
+    Pointer<WasmerExportDescriptor>, Pointer<WasmerByteArray>);
+
+// wasmer_import_descriptors
+typedef NativeWasmerImportDescriptorsFn = Void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerImportDescriptors>>);
+typedef WasmerImportDescriptorsFn = void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerImportDescriptors>>);
+
+// wasmer_import_descriptors_destroy
+typedef NativeWasmerImportDescriptorsDestroyFn = Void Function(
+    Pointer<WasmerImportDescriptors>);
+typedef WasmerImportDescriptorsDestroyFn = void Function(
+    Pointer<WasmerImportDescriptors>);
+
+// wasmer_import_descriptors_len
+typedef NativeWasmerImportDescriptorsLenFn = Int32 Function(
+    Pointer<WasmerImportDescriptors>);
+typedef WasmerImportDescriptorsLenFn = int Function(
+    Pointer<WasmerImportDescriptors>);
+
+// wasmer_import_descriptors_get
+typedef NativeWasmerImportDescriptorsGetFn = Pointer<WasmerImportDescriptor>
+    Function(Pointer<WasmerImportDescriptors>, Int32);
+typedef WasmerImportDescriptorsGetFn = Pointer<WasmerImportDescriptor> Function(
+    Pointer<WasmerImportDescriptors>, int);
+
+// wasmer_import_descriptor_kind
+typedef NativeWasmerImportDescriptorKindFn = Uint32 Function(
+    Pointer<WasmerImportDescriptor>);
+typedef WasmerImportDescriptorKindFn = int Function(
+    Pointer<WasmerImportDescriptor>);
+
+// wasmer_import_descriptor_module_name_ptr
+typedef NativeWasmerImportDescriptorModuleNamePtrFn = Void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+typedef WasmerImportDescriptorModuleNamePtrFn = void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+
+// wasmer_import_descriptor_name_ptr
+typedef NativeWasmerImportDescriptorNamePtrFn = Void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+typedef WasmerImportDescriptorNamePtrFn = void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+
+// wasmer_export_name_ptr
+typedef NativeWasmerExportNamePtrFn = Void Function(
+    Pointer<WasmerExport>, Pointer<WasmerByteArray>);
+typedef WasmerExportNamePtrFn = void Function(
+    Pointer<WasmerExport>, Pointer<WasmerByteArray>);
 
 // wasmer_export_kind
 typedef NativeWasmerExportKindFn = Uint32 Function(Pointer<WasmerExport>);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 08b0c79..a2226fb 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -5542,7 +5542,13 @@
       "  factory MyInterface.named(value) = MyExtraHop.hop;\n"
       "  factory MyInterface.multiply(value) = MyClass.multiply;\n"
       "  MyInterface.notfound(value);\n"
-      "}\n";
+      "}\n"
+      "\n"
+      "class _MyClass {\n"
+      "  _MyClass._() : foo = 7 {}\n"
+      "  var foo;\n"
+      "}\n"
+      "\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   Dart_Handle type =
@@ -5551,6 +5557,10 @@
   Dart_Handle intf =
       Dart_GetNonNullableType(lib, NewString("MyInterface"), 0, NULL);
   EXPECT_VALID(intf);
+  Dart_Handle private_type =
+      Dart_GetNonNullableType(lib, NewString("_MyClass"), 0, NULL);
+  EXPECT_VALID(private_type);
+
   Dart_Handle args[1];
   args[0] = Dart_NewInteger(11);
   Dart_Handle bad_args[1];
@@ -5641,6 +5651,14 @@
   EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
   EXPECT_EQ(-11, int_value);
 
+  // Invoke a hidden named constructor on a hidden type.
+  result = Dart_New(private_type, NewString("_"), 0, NULL);
+  EXPECT_VALID(result);
+  int_value = 0;
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
+  EXPECT_EQ(7, int_value);
+
   // Allocate object and invoke a hidden named constructor.
   obj = Dart_Allocate(type);
   EXPECT_VALID(obj);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e19f14e..9e253e3 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -22650,8 +22650,13 @@
     int32_t ch = T1::CharAt(str1, pos);
     pos++;
 
+    if ((str2_pos < str2_len) && (ch == T2::CharAt(str2, str2_pos))) {
+      str2_pos++;
+      continue;
+    }
+
     if (ch == Library::kPrivateKeySeparator) {
-      // Consume a private key separator.
+      // Consume a private key separator if str1 has it but str2 does not.
       while ((pos < len) && (T1::CharAt(str1, pos) != '.') &&
              (T1::CharAt(str1, pos) != '&')) {
         pos++;
@@ -22659,10 +22664,8 @@
       // Resume matching characters.
       continue;
     }
-    if ((str2_pos == str2_len) || (ch != T2::CharAt(str2, str2_pos))) {
-      return false;
-    }
-    str2_pos++;
+
+    return false;
   }
 
   // We have reached the end of mangled_name string.
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 68f2de9..66adb2f 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3208,6 +3208,12 @@
   bare_name = OneByteString::New("foo.named");
   EXPECT(String::EqualsIgnoringPrivateKey(mangled_name, bare_name));
 
+  // Named double-private constructor match where the caller knows the private
+  // key.  Yes, this also happens.
+  mangled_name = OneByteString::New("foo@12345.named@12345");
+  bare_name = OneByteString::New("foo@12345.named");
+  EXPECT(String::EqualsIgnoringPrivateKey(mangled_name, bare_name));
+
   // Named double-private constructor mismatch.
   mangled_name = OneByteString::New("foo@12345.name@12345");
   bare_name = OneByteString::New("foo.named");
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 72f9851..ae81ef8 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -586,15 +586,16 @@
   visibility = [ ":create_common_sdk" ]
   deps = [
     ":copy_libraries",
-    "../third_party/wasmer:wasmer_lib",
+    "../third_party/wasmer:wasmer_wrapper",
   ]
-  outputs = [ "$root_out_dir/dart-sdk/bin/third_party/wasmer/{{source_file_part}}" ]
+  outputs =
+      [ "$root_out_dir/dart-sdk/bin/third_party/wasmer/{{source_file_part}}" ]
   if (is_win) {
-    sources = [ "$target_out_dir/../third_party/wasmer/wasmer.dll" ]
+    sources = [ "$target_out_dir/../../wasmer_wrapper.dll" ]
   } else if (is_mac) {
-    sources = [ "$target_out_dir/../third_party/wasmer/libwasmer.dylib" ]
+    sources = [ "$target_out_dir/../../libwasmer_wrapper.dylib" ]
   } else {
-    sources = [ "$target_out_dir/../third_party/wasmer/libwasmer.so" ]
+    sources = [ "$target_out_dir/../../libwasmer_wrapper.so" ]
   }
 }
 
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 0d5160f..8da9d66 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -665,7 +665,7 @@
   set effect(AnimationEffectReadOnly? value) native;
 
   Future<Animation> get finished =>
-      promiseToFuture<Animation>(JS("", "#.finished", this));
+      promiseToFuture<Animation>(JS("creates:Animation;", "#.finished", this));
 
   String? get id native;
 
@@ -678,7 +678,7 @@
   set playbackRate(num? value) native;
 
   Future<Animation> get ready =>
-      promiseToFuture<Animation>(JS("", "#.ready", this));
+      promiseToFuture<Animation>(JS("creates:Animation;", "#.ready", this));
 
   num? get startTime native;
 
@@ -1354,13 +1354,18 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture<BackgroundFetchRegistration>(
-        JS("", "#.fetch(#, #, #)", this, id, requests, options_dict));
+    return promiseToFuture<BackgroundFetchRegistration>(JS(
+        "creates:BackgroundFetchRegistration;",
+        "#.fetch(#, #, #)",
+        this,
+        id,
+        requests,
+        options_dict));
   }
 
   Future<BackgroundFetchRegistration> get(String id) =>
       promiseToFuture<BackgroundFetchRegistration>(
-          JS("", "#.get(#)", this, id));
+          JS("creates:BackgroundFetchRegistration;", "#.get(#)", this, id));
 
   Future<List<dynamic>> getIds() =>
       promiseToFuture<List<dynamic>>(JS("", "#.getIds()", this));
@@ -1676,10 +1681,11 @@
 
   Future arrayBuffer() => promiseToFuture(JS("", "#.arrayBuffer()", this));
 
-  Future<Blob> blob() => promiseToFuture<Blob>(JS("", "#.blob()", this));
+  Future<Blob> blob() =>
+      promiseToFuture<Blob>(JS("creates:Blob;", "#.blob()", this));
 
   Future<FormData> formData() =>
-      promiseToFuture<FormData>(JS("", "#.formData()", this));
+      promiseToFuture<FormData>(JS("creates:FormData;", "#.formData()", this));
 
   Future json() => promiseToFuture(JS("", "#.json()", this));
 
@@ -2020,11 +2026,11 @@
       options_dict = convertDartToNative_Dictionary(options);
     }
     return promiseToFuture(
-        JS("", "#.match(#, #)", this, request, options_dict));
+        JS("creates:_Response;", "#.match(#, #)", this, request, options_dict));
   }
 
   Future open(String cacheName) =>
-      promiseToFuture(JS("", "#.open(#)", this, cacheName));
+      promiseToFuture(JS("creates:_Cache;", "#.open(#)", this, cacheName));
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -3065,8 +3071,8 @@
         JS("", "#.matchAll(#)", this, options_dict));
   }
 
-  Future<WindowClient> openWindow(String url) =>
-      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
+  Future<WindowClient> openWindow(String url) => promiseToFuture<WindowClient>(
+      JS("creates:WindowClient;", "#.openWindow(#)", this, url));
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -3318,7 +3324,8 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture(JS("", "#.create(#)", this, options_dict));
+    return promiseToFuture(
+        JS("creates:Credential;", "#.create(#)", this, options_dict));
   }
 
   Future get([Map? options]) {
@@ -3326,7 +3333,8 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture(JS("", "#.get(#)", this, options_dict));
+    return promiseToFuture(
+        JS("creates:Credential;", "#.get(#)", this, options_dict));
   }
 
   Future preventSilentAccess() =>
@@ -3335,8 +3343,8 @@
   Future requireUserMediation() =>
       promiseToFuture(JS("", "#.requireUserMediation()", this));
 
-  Future store(Credential credential) =>
-      promiseToFuture(JS("", "#.store(#)", this, credential));
+  Future store(Credential credential) => promiseToFuture(
+      JS("creates:Credential;", "#.store(#)", this, credential));
 }
 // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -16488,7 +16496,7 @@
   set featureSettings(String? value) native;
 
   Future<FontFace> get loaded =>
-      promiseToFuture<FontFace>(JS("", "#.loaded", this));
+      promiseToFuture<FontFace>(JS("creates:FontFace;", "#.loaded", this));
 
   String? get status native;
 
@@ -16513,7 +16521,7 @@
   set weight(String? value) native;
 
   Future<FontFace> load() =>
-      promiseToFuture<FontFace>(JS("", "#.load()", this));
+      promiseToFuture<FontFace>(JS("creates:FontFace;", "#.load()", this));
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -18864,13 +18872,13 @@
 
   Future<PhotoCapabilities> getPhotoCapabilities() =>
       promiseToFuture<PhotoCapabilities>(
-          JS("", "#.getPhotoCapabilities()", this));
+          JS("creates:PhotoCapabilities;", "#.getPhotoCapabilities()", this));
 
   Future<Map<String, dynamic>?> getPhotoSettings() =>
       promiseToFutureAsMap(JS("", "#.getPhotoSettings()", this));
 
-  Future<ImageBitmap> grabFrame() =>
-      promiseToFuture<ImageBitmap>(JS("", "#.grabFrame()", this));
+  Future<ImageBitmap> grabFrame() => promiseToFuture<ImageBitmap>(
+      JS("creates:ImageBitmap;", "#.grabFrame()", this));
 
   Future setOptions(Map photoSettings) {
     var photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
@@ -18883,7 +18891,7 @@
       photoSettings_dict = convertDartToNative_Dictionary(photoSettings);
     }
     return promiseToFuture<Blob>(
-        JS("", "#.takePhoto(#)", this, photoSettings_dict));
+        JS("creates:Blob;", "#.takePhoto(#)", this, photoSettings_dict));
   }
 }
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
@@ -20468,14 +20476,20 @@
 
   Future<MediaCapabilitiesInfo> decodingInfo(Map configuration) {
     var configuration_dict = convertDartToNative_Dictionary(configuration);
-    return promiseToFuture<MediaCapabilitiesInfo>(
-        JS("", "#.decodingInfo(#)", this, configuration_dict));
+    return promiseToFuture<MediaCapabilitiesInfo>(JS(
+        "creates:MediaCapabilitiesInfo;",
+        "#.decodingInfo(#)",
+        this,
+        configuration_dict));
   }
 
   Future<MediaCapabilitiesInfo> encodingInfo(Map configuration) {
     var configuration_dict = convertDartToNative_Dictionary(configuration);
-    return promiseToFuture<MediaCapabilitiesInfo>(
-        JS("", "#.encodingInfo(#)", this, configuration_dict));
+    return promiseToFuture<MediaCapabilitiesInfo>(JS(
+        "creates:MediaCapabilitiesInfo;",
+        "#.encodingInfo(#)",
+        this,
+        configuration_dict));
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -20540,8 +20554,8 @@
     if (constraints != null) {
       constraints_dict = convertDartToNative_Dictionary(constraints);
     }
-    return promiseToFuture<MediaStream>(
-        JS("", "#.getUserMedia(#)", this, constraints_dict));
+    return promiseToFuture<MediaStream>(JS(
+        "creates:MediaStream;", "#.getUserMedia(#)", this, constraints_dict));
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -20849,7 +20863,7 @@
   String? get keySystem native;
 
   Future createMediaKeys() =>
-      promiseToFuture(JS("", "#.createMediaKeys()", this));
+      promiseToFuture(JS("creates:MediaKeys;", "#.createMediaKeys()", this));
 
   Map getConfiguration() {
     return convertNativeToDart_Dictionary(_getConfiguration_1())!;
@@ -22741,10 +22755,11 @@
   List<Gamepad?> _getGamepads() native;
 
   Future<RelatedApplication> getInstalledRelatedApps() =>
-      promiseToFuture<RelatedApplication>(
-          JS("", "#.getInstalledRelatedApps()", this));
+      promiseToFuture<RelatedApplication>(JS(
+          "creates:RelatedApplication;", "#.getInstalledRelatedApps()", this));
 
-  Future getVRDisplays() => promiseToFuture(JS("", "#.getVRDisplays()", this));
+  Future getVRDisplays() =>
+      promiseToFuture(JS("creates:VRDisplay;", "#.getVRDisplays()", this));
 
   @Unstable()
   void registerProtocolHandler(String scheme, String url, String title) native;
@@ -22776,8 +22791,12 @@
 
   Future requestMediaKeySystemAccess(
           String keySystem, List<Map> supportedConfigurations) =>
-      promiseToFuture(JS("", "#.requestMediaKeySystemAccess(#, #)", this,
-          keySystem, supportedConfigurations));
+      promiseToFuture(JS(
+          "creates:MediaKeySystemAccess;",
+          "#.requestMediaKeySystemAccess(#, #)",
+          this,
+          keySystem,
+          supportedConfigurations));
 
   bool sendBeacon(String url, Object? data) native;
 
@@ -23981,7 +24000,7 @@
       options_dict = convertDartToNative_Dictionary(options);
     }
     return promiseToFuture<Blob>(
-        JS("", "#.convertToBlob(#)", this, options_dict));
+        JS("creates:Blob;", "#.convertToBlob(#)", this, options_dict));
   }
 
   Object? getContext(String contextType, [Map? attributes]) {
@@ -24990,8 +25009,8 @@
   Future<bool> canMakePayment() =>
       promiseToFuture<bool>(JS("", "#.canMakePayment()", this));
 
-  Future<PaymentResponse> show() =>
-      promiseToFuture<PaymentResponse>(JS("", "#.show()", this));
+  Future<PaymentResponse> show() => promiseToFuture<PaymentResponse>(
+      JS("creates:PaymentResponse;", "#.show()", this));
 }
 
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25029,8 +25048,8 @@
 
   Object? get total native;
 
-  Future<WindowClient> openWindow(String url) =>
-      promiseToFuture<WindowClient>(JS("", "#.openWindow(#)", this, url));
+  Future<WindowClient> openWindow(String url) => promiseToFuture<WindowClient>(
+      JS("creates:WindowClient;", "#.openWindow(#)", this, url));
 
   void respondWith(Future response) native;
 }
@@ -25463,23 +25482,23 @@
   Future<PermissionStatus> query(Map permission) {
     var permission_dict = convertDartToNative_Dictionary(permission);
     return promiseToFuture<PermissionStatus>(
-        JS("", "#.query(#)", this, permission_dict));
+        JS("creates:PermissionStatus;", "#.query(#)", this, permission_dict));
   }
 
   Future<PermissionStatus> request(Map permissions) {
     var permissions_dict = convertDartToNative_Dictionary(permissions);
-    return promiseToFuture<PermissionStatus>(
-        JS("", "#.request(#)", this, permissions_dict));
+    return promiseToFuture<PermissionStatus>(JS(
+        "creates:PermissionStatus;", "#.request(#)", this, permissions_dict));
   }
 
   Future<PermissionStatus> requestAll(List<Map> permissions) =>
-      promiseToFuture<PermissionStatus>(
-          JS("", "#.requestAll(#)", this, permissions));
+      promiseToFuture<PermissionStatus>(JS(
+          "creates:PermissionStatus;", "#.requestAll(#)", this, permissions));
 
   Future<PermissionStatus> revoke(Map permission) {
     var permission_dict = convertDartToNative_Dictionary(permission);
     return promiseToFuture<PermissionStatus>(
-        JS("", "#.revoke(#)", this, permission_dict));
+        JS("creates:PermissionStatus;", "#.revoke(#)", this, permission_dict));
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -25898,7 +25917,7 @@
 
   Future<PresentationConnectionList> get connectionList =>
       promiseToFuture<PresentationConnectionList>(
-          JS("", "#.connectionList", this));
+          JS("creates:PresentationConnectionList;", "#.connectionList", this));
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -25928,14 +25947,15 @@
 
   Future<PresentationAvailability> getAvailability() =>
       promiseToFuture<PresentationAvailability>(
-          JS("", "#.getAvailability()", this));
+          JS("creates:PresentationAvailability;", "#.getAvailability()", this));
 
   Future<PresentationConnection> reconnect(String id) =>
       promiseToFuture<PresentationConnection>(
-          JS("", "#.reconnect(#)", this, id));
+          JS("creates:PresentationConnection;", "#.reconnect(#)", this, id));
 
   Future<PresentationConnection> start() =>
-      promiseToFuture<PresentationConnection>(JS("", "#.start()", this));
+      promiseToFuture<PresentationConnection>(
+          JS("creates:PresentationConnection;", "#.start()", this));
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -26102,7 +26122,8 @@
   static List<String>? get supportedContentEncodings native;
 
   Future<PushSubscription> getSubscription() =>
-      promiseToFuture<PushSubscription>(JS("", "#.getSubscription()", this));
+      promiseToFuture<PushSubscription>(
+          JS("creates:PushSubscription;", "#.getSubscription()", this));
 
   Future permissionState([Map? options]) {
     var options_dict = null;
@@ -26118,7 +26139,7 @@
       options_dict = convertDartToNative_Dictionary(options);
     }
     return promiseToFuture<PushSubscription>(
-        JS("", "#.subscribe(#)", this, options_dict));
+        JS("creates:PushSubscription;", "#.subscribe(#)", this, options_dict));
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -26936,8 +26957,11 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture<RtcSessionDescription>(
-        JS("", "#.createAnswer(#)", this, options_dict));
+    return promiseToFuture<RtcSessionDescription>(JS(
+        "creates:RtcSessionDescription;",
+        "#.createAnswer(#)",
+        this,
+        options_dict));
   }
 
   @JSName('createDTMFSender')
@@ -26961,8 +26985,11 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture<RtcSessionDescription>(
-        JS("", "#.createOffer(#)", this, options_dict));
+    return promiseToFuture<RtcSessionDescription>(JS(
+        "creates:RtcSessionDescription;",
+        "#.createOffer(#)",
+        this,
+        options_dict));
   }
 
   List<MediaStream> getLocalStreams() native;
@@ -26973,8 +27000,8 @@
 
   List<RtcRtpSender> getSenders() native;
 
-  Future<RtcStatsReport> getStats() =>
-      promiseToFuture<RtcStatsReport>(JS("", "#.getStats()", this));
+  Future<RtcStatsReport> getStats() => promiseToFuture<RtcStatsReport>(
+      JS("creates:RtcStatsReport;", "#.getStats()", this));
 
   void removeStream(MediaStream? stream) native;
 
@@ -27762,11 +27789,15 @@
   ServiceWorker? get controller native;
 
   Future<ServiceWorkerRegistration> get ready =>
-      promiseToFuture<ServiceWorkerRegistration>(JS("", "#.ready", this));
+      promiseToFuture<ServiceWorkerRegistration>(
+          JS("creates:ServiceWorkerRegistration;", "#.ready", this));
 
   Future<ServiceWorkerRegistration> getRegistration([String? documentURL]) =>
-      promiseToFuture<ServiceWorkerRegistration>(
-          JS("", "#.getRegistration(#)", this, documentURL));
+      promiseToFuture<ServiceWorkerRegistration>(JS(
+          "creates:ServiceWorkerRegistration;",
+          "#.getRegistration(#)",
+          this,
+          documentURL));
 
   Future<List<dynamic>> getRegistrations() =>
       promiseToFuture<List<dynamic>>(JS("", "#.getRegistrations()", this));
@@ -27776,8 +27807,12 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture<ServiceWorkerRegistration>(
-        JS("", "#.register(#, #)", this, url, options_dict));
+    return promiseToFuture<ServiceWorkerRegistration>(JS(
+        "creates:ServiceWorkerRegistration;",
+        "#.register(#, #)",
+        this,
+        url,
+        options_dict));
   }
 
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
@@ -31207,8 +31242,8 @@
     if (options != null) {
       options_dict = convertDartToNative_Dictionary(options);
     }
-    return promiseToFuture(
-        JS("", "#.requestFrameOfReference(#, #)", this, type, options_dict));
+    return promiseToFuture(JS("creates:VRFrameOfReference;",
+        "#.requestFrameOfReference(#, #)", this, type, options_dict));
   }
 
   Stream<Event> get onBlur => blurEvent.forTarget(this);
@@ -32854,7 +32889,8 @@
     if (init != null) {
       init_dict = convertDartToNative_Dictionary(init);
     }
-    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
+    return promiseToFuture(
+        JS("creates:_Response;", "#.fetch(#, #)", this, input, init_dict));
   }
 
   /**
@@ -33759,11 +33795,11 @@
 
   String? get visibilityState native;
 
-  Future<WindowClient> focus() =>
-      promiseToFuture<WindowClient>(JS("", "#.focus()", this));
+  Future<WindowClient> focus() => promiseToFuture<WindowClient>(
+      JS("creates:WindowClient;", "#.focus()", this));
 
-  Future<WindowClient> navigate(String url) =>
-      promiseToFuture<WindowClient>(JS("", "#.navigate(#)", this, url));
+  Future<WindowClient> navigate(String url) => promiseToFuture<WindowClient>(
+      JS("creates:WindowClient;", "#.navigate(#)", this, url));
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -33923,7 +33959,8 @@
     if (init != null) {
       init_dict = convertDartToNative_Dictionary(init);
     }
-    return promiseToFuture(JS("", "#.fetch(#, #)", this, input, init_dict));
+    return promiseToFuture(
+        JS("creates:_Response;", "#.fetch(#, #)", this, input, init_dict));
   }
 
   void importScripts(String urls) native;
@@ -34334,8 +34371,8 @@
     throw new UnsupportedError("Not supported");
   }
 
-  Future<BudgetState> getBudget() =>
-      promiseToFuture<BudgetState>(JS("", "#.getBudget()", this));
+  Future<BudgetState> getBudget() => promiseToFuture<BudgetState>(
+      JS("creates:BudgetState;", "#.getBudget()", this));
 
   Future<double> getCost(String operation) =>
       promiseToFuture<double>(JS("", "#.getCost(#)", this, operation));
@@ -34375,8 +34412,8 @@
     throw new UnsupportedError("Not supported");
   }
 
-  Future<DataTransfer> read() =>
-      promiseToFuture<DataTransfer>(JS("", "#.read()", this));
+  Future<DataTransfer> read() => promiseToFuture<DataTransfer>(
+      JS("creates:DataTransfer;", "#.read()", this));
 
   Future<String> readText() =>
       promiseToFuture<String>(JS("", "#.readText()", this));
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index da12ab3..a12d2fe 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -682,8 +682,13 @@
   Future<AudioBuffer> decodeAudioData(ByteBuffer audioData,
           [DecodeSuccessCallback? successCallback,
           DecodeErrorCallback? errorCallback]) =>
-      promiseToFuture<AudioBuffer>(JS("", "#.decodeAudioData(#, #, #)", this,
-          audioData, successCallback, errorCallback));
+      promiseToFuture<AudioBuffer>(JS(
+          "creates:AudioBuffer;",
+          "#.decodeAudioData(#, #, #)",
+          this,
+          audioData,
+          successCallback,
+          errorCallback));
 
   Future resume() => promiseToFuture(JS("", "#.resume()", this));
 }
@@ -1075,8 +1080,8 @@
 
   int? get length native;
 
-  Future<AudioBuffer> startRendering() =>
-      promiseToFuture<AudioBuffer>(JS("", "#.startRendering()", this));
+  Future<AudioBuffer> startRendering() => promiseToFuture<AudioBuffer>(
+      JS("creates:AudioBuffer;", "#.startRendering()", this));
 
   @JSName('suspend')
   Future suspendFor(num suspendTime) =>
diff --git a/tests/lib/mirrors/library_uri_package_test.dart b/tests/lib/mirrors/library_uri_package_test.dart
index 0116005..e546722 100644
--- a/tests/lib/mirrors/library_uri_package_test.dart
+++ b/tests/lib/mirrors/library_uri_package_test.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test library uri for a library read as a package .
+// Test library uri for a library read as a package.
 
 library MirrorsTest;
 
 import 'dart:mirrors';
-import 'package:args/args.dart';
+import 'package:expect/expect.dart';
 import 'package:async_helper/async_minitest.dart';
 
 testLibraryUri(var value, Uri expectedUri) {
@@ -26,6 +26,6 @@
   var mirrors = currentMirrorSystem();
   test("Test package library uri", () {
     testLibraryUri(
-        new ArgParser(), Uri.parse('package:args/src/arg_parser.dart'));
+        ExpectException(""), Uri.parse('package:expect/expect.dart'));
   });
 }
diff --git a/third_party/wasmer/BUILD.gn b/third_party/wasmer/BUILD.gn
index 5549fc6..afd36a8 100644
--- a/third_party/wasmer/BUILD.gn
+++ b/third_party/wasmer/BUILD.gn
@@ -1,11 +1,17 @@
 import("../../build/rust/rust.gni")
 
-component("wasmer") {
-  public = [ "wasmer.hh" ]
+shared_library("wasmer_wrapper") {
+  sources = [
+    "wasmer.hh",
+    "wasmer_wrapper.cc",
+  ]
   deps = [ ":wasmer_lib" ]
+  if (is_linux) {
+    libs = [ "rt" ]
+  }
+  ldflags = [ "-Wl,--no-as-needed" ]  # Force linking of all wasmer symbols.
 }
 
 rust_library("wasmer_lib") {
   lib_name = "wasmer"
-  shared = true
 }
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
index 67c601b..bfe6172 100644
--- a/third_party/wasmer/Cargo.toml
+++ b/third_party/wasmer/Cargo.toml
@@ -4,7 +4,7 @@
 
 [lib]
 name = "wasmer"
-crate-type = ["dylib"]
+crate-type = ["staticlib"]
 path = "wasmer.rs"
 
 [dependencies]
diff --git a/third_party/wasmer/wasmer_wrapper.cc b/third_party/wasmer/wasmer_wrapper.cc
new file mode 100644
index 0000000..b014268
--- /dev/null
+++ b/third_party/wasmer/wasmer_wrapper.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Wraps several functions from wasmer.hh, so that they take and return all
+// structs by pointer, rather than by value. This is necessary because Dart FFI
+// doesn't support passing structs by value yet (once it does, we can delete
+// this wrapper).
+
+#include "wasmer.hh"
+
+extern "C" {
+// Wraps wasmer_export_name.
+void wasmer_export_name_ptr(wasmer_export_t* export_,
+                            wasmer_byte_array* out_name) {
+  *out_name = wasmer_export_name(export_);
+}
+
+// Wraps wasmer_export_descriptor_name.
+void wasmer_export_descriptor_name_ptr(
+    wasmer_export_descriptor_t* export_descriptor,
+    wasmer_byte_array* out_name) {
+  *out_name = wasmer_export_descriptor_name(export_descriptor);
+}
+
+// Wraps wasmer_import_descriptor_module_name.
+void wasmer_import_descriptor_module_name_ptr(
+    wasmer_import_descriptor_t* import_descriptor,
+    wasmer_byte_array* out_name) {
+  *out_name = wasmer_import_descriptor_module_name(import_descriptor);
+}
+
+// Wraps wasmer_import_descriptor_name.
+void wasmer_import_descriptor_name_ptr(
+    wasmer_import_descriptor_t* import_descriptor,
+    wasmer_byte_array* out_name) {
+  *out_name = wasmer_import_descriptor_name(import_descriptor);
+}
+}
diff --git a/tools/VERSION b/tools/VERSION
index 775d3f3..84e9a2e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 125
+PRERELEASE 126
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 0761fe6..3b35750 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -890,53 +890,64 @@
 promise_attributes = monitored.Dict(
     'systemhtml.promise_attr_type', {
         "Animation.finished": {
-            "type": "Animation"
+            "type": "Animation",
+            "creates": "Animation"
         },
         "Animation.ready": {
-            "type": "Animation"
+            "type": "Animation",
+            "creates": "Animation"
         },
         "BeforeInstallPromptEvent.userChoice": {
             "type": "dictionary"
         },
         "FontFace.loaded": {
-            "type": "FontFace"
+            "type": "FontFace",
+            "creates": "FontFace"
         },
         "FontFaceSet.ready": {
-            "type": "FontFaceSet"
+            "type": "FontFaceSet",
+            "creates": "FontFaceSet"
         },
         "MediaKeySession.closed": {
             "type": "void"
         },
         "PresentationReceiver.connectionList": {
-            "type": "PresentationConnectionList"
+            "type": "PresentationConnectionList",
+            "creates": "PresentationConnectionList"
         },
         "ServiceWorkerContainer.ready": {
-            "type": "ServiceWorkerRegistration"
+            "type": "ServiceWorkerRegistration",
+            "creates": "ServiceWorkerRegistration"
         },
     })
 
 promise_operations = monitored.Dict(
     'systemhtml.promise_oper_type', {
         "Clipboard.read": {
-            "type": "DataTransfer"
+            "type": "DataTransfer",
+            "creates": "DataTransfer"
         },
         "Clipboard.readText": {
             "type": "String"
         },
         "FontFace.load": {
-            "type": "FontFace"
+            "type": "FontFace",
+            "creates": "FontFace"
         },
         "FontFaceSet.load": {
             "type": "List<dynamic>"
         },
         "OffscreenCanvas.load": {
-            "type": "Blob"
+            "type": "Blob",
+            "creates": "Blob"
         },
         "BackgroundFetchManager.fetch": {
-            "type": "BackgroundFetchRegistration"
+            "type": "BackgroundFetchRegistration",
+            "creates": "BackgroundFetchRegistration"
         },
         "BackgroundFetchManager.get": {
-            "type": "BackgroundFetchRegistration"
+            "type": "BackgroundFetchRegistration",
+            "creates": "BackgroundFetchRegistration"
         },
         "BackgroundFetchManager.getIds": {
             "type": "List<dynamic>"
@@ -951,49 +962,60 @@
             "type": "double"
         },
         "BudgetService.getBudget": {
-            "type": "BudgetState"
+            "type": "BudgetState",
+            "creates": "BudgetState"
         },
         "BudgetService.reserve": {
             "type": "bool"
         },
         "Body.blob": {
-            "type": "Blob"
+            "type": "Blob",
+            "creates": "Blob"
         },
         "Body.formData": {
-            "type": "FormData"
+            "type": "FormData",
+            "creates": "FormData"
         },
         "Body.text": {
             "type": "String"
         },
         "ImageCapture.getPhotoCapabilities": {
-            "type": "PhotoCapabilities"
+            "type": "PhotoCapabilities",
+            "creates": "PhotoCapabilities"
         },
         "ImageCapture.getPhotoSettings": {
             "type": "dictionary"
         },
         "ImageCapture.takePhoto": {
-            "type": "Blob"
+            "type": "Blob",
+            "creates": "Blob"
         },
         "ImageCapture.grabFrame": {
-            "type": "ImageBitmap"
+            "type": "ImageBitmap",
+            "creates": "ImageBitmap"
         },
         "Navigator.getInstalledRelatedApps": {
-            "type": "RelatedApplication"
+            "type": "RelatedApplication",
+            "creates": "RelatedApplication"
         },
         "OffscreenCanvas.convertToBlob": {
-            "type": "Blob"
+            "type": "Blob",
+            "creates": "Blob"
         },
         "MediaCapabilities.decodingInfo": {
-            "type": "MediaCapabilitiesInfo"
+            "type": "MediaCapabilitiesInfo",
+            "creates": "MediaCapabilitiesInfo"
         },
         "MediaCapabilities.encodingInfo": {
-            "type": "MediaCapabilitiesInfo"
+            "type": "MediaCapabilitiesInfo",
+            "creates": "MediaCapabilitiesInfo"
         },
         "MediaDevices.enumerateDevices": {
             "type": "List<dynamic>"
         },
         "MediaDevices.getUserMedia": {
-            "type": "MediaStream"
+            "type": "MediaStream",
+            "creates": "MediaStream"
         },
         "ServiceWorkerRegistration.getNotifications": {
             "type": "List<dynamic>"
@@ -1011,53 +1033,68 @@
             "type": "bool"
         },
         "PaymentRequest.show": {
-            "type": "PaymentResponse"
+            "type": "PaymentResponse",
+            "creates": "PaymentResponse"
         },
         "PaymentRequest.canMakePayment": {
             "type": "bool"
         },
         "PaymentRequestEvent.openWindow": {
-            "type": "WindowClient"
+            "type": "WindowClient",
+            "creates": "WindowClient"
         },
         "RTCPeerConnection.createOffer": {
-            "type": "RtcSessionDescription"
+            "type": "RtcSessionDescription",
+            "creates": "RtcSessionDescription"
         },
         "RTCPeerConnection.createAnswer": {
-            "type": "RtcSessionDescription"
+            "type": "RtcSessionDescription",
+            "creates": "RtcSessionDescription"
         },
         "RTCPeerConnection.getStats": {
             "type": "RtcStatsReport",
-            "maplike": "RTCStatsReport"
+            "maplike": "RTCStatsReport",
+            "creates": "RtcStatsReport"
         },
         "RTCPeerConnection.generateCertificate": {
-            "type": "RtcCertificate"
+            "type": "RtcCertificate",
+            "creates": "RtcCertificate"
         },
         "Permissions.query": {
-            "type": "PermissionStatus"
+            "type": "PermissionStatus",
+            "creates": "PermissionStatus"
         },
         "Permissions.request": {
-            "type": "PermissionStatus"
+            "type": "PermissionStatus",
+            "creates": "PermissionStatus"
         },
         "Permissions.revoke": {
-            "type": "PermissionStatus"
+            "type": "PermissionStatus",
+            "creates": "PermissionStatus"
         },
         "Permissions.requestAll": {
-            "type": "PermissionStatus"
+            "type": "PermissionStatus",
+            "creates": "PermissionStatus"
         },
         "PresentationRequest.start": {
-            "type": "PresentationConnection"
+            "type": "PresentationConnection",
+            "creates": "PresentationConnection"
         },
         "PresentationRequest.reconnect": {
-            "type": "PresentationConnection"
+            "type": "PresentationConnection",
+            "creates": "PresentationConnection"
         },
         "PresentationRequest.getAvailability": {
-            "type": "PresentationAvailability"
+            "type": "PresentationAvailability",
+            "creates": "PresentationAvailability"
         },
         "PushManager.subscribe": {
-            "type": "PushSubscription"
+            "type": "PushSubscription",
+            "creates": "PushSubscription"
         },
         "PushManager.getSubscription": {
-            "type": "PushSubscription"
+            "type": "PushSubscription",
+            "creates": "PushSubscription"
         },
         "PushSubscription.unsubscribe": {
             "type": "bool"
@@ -1078,31 +1115,36 @@
             "type": "List<dynamic>"
         },
         "Clients.openWindow": {
-            "type": "WindowClient"
+            "type": "WindowClient",
+            "creates": "WindowClient"
         },
         "NavigationPreloadManager.getState": {
             "type": "dictionary"
         },
         "ServiceWorkerContainer.register": {
-            "type": "ServiceWorkerRegistration"
+            "type": "ServiceWorkerRegistration",
+            "creates": "ServiceWorkerRegistration"
         },
         "ServiceWorkerContainer.getRegistration": {
-            "type": "ServiceWorkerRegistration"
+            "type": "ServiceWorkerRegistration",
+            "creates": "ServiceWorkerRegistration"
         },
         "ServiceWorkerContainer.getRegistrations": {
             "type": "List<dynamic>"
         },
         "ServiceWorkerGlobalScope.fetch": {
-            "type": "Response"
+            "creates": "_Response"
         },
         "ServiceWorkerRegistration.unregister": {
             "type": "bool"
         },
         "WindowClient.focus": {
-            "type": "WindowClient"
+            "type": "WindowClient",
+            "creates": "WindowClient"
         },
         "WindowClient.navigate": {
-            "type": "WindowClient"
+            "type": "WindowClient",
+            "creates": "WindowClient"
         },
         "BarcodeDetector.detect": {
             "type": "List<dynamic>"
@@ -1114,10 +1156,48 @@
             "type": "List<dynamic>"
         },
         "BaseAudioContext.decodeAudioData": {
-            "type": "AudioBuffer"
+            "type": "AudioBuffer",
+            "creates": "AudioBuffer"
         },
         "OfflineAudioContext.startRendering": {
-            "type": "AudioBuffer"
+            "type": "AudioBuffer",
+            "creates": "AudioBuffer"
+        },
+        "CacheStorage.match": {
+            "creates": "_Response"
+        },
+        "CacheStorage.open": {
+            "creates": "_Cache"
+        },
+        "CredentialsContainer.create": {
+            "creates": "Credential"
+        },
+        "CredentialsContainer.get": {
+            "creates": "Credential"
+        },
+        "CredentialsContainer.store": {
+            "creates": "Credential"
+        },
+        "FetchEvent.preloadResponse": {
+            "creates": "_Response"
+        },
+        "MediaKeySystemAccess.createMediaKeys": {
+            "creates": "MediaKeys"
+        },
+        "Navigator.getVRDisplays": {
+            "creates": "VRDisplay"
+        },
+        "Navigator.requestMediaKeySystemAccess": {
+            "creates": "MediaKeySystemAccess"
+        },
+        "VRSession.requestFrameOfReference": {
+            "creates": "VRFrameOfReference"
+        },
+        "Window.fetch": {
+            "creates": "_Response"
+        },
+        "WorkerGlobalScope.fetch": {
+            "creates": "_Response"
         },
     })
 
@@ -1492,11 +1572,13 @@
                 promiseFound = _GetPromiseAttributeType(lookupOp)
                 promiseType = 'Future'
                 promiseCall = 'promiseToFuture'
+                type_description = ''
                 if promiseFound is not (None):
+                    paramType = promiseFound.get('type')
                     if 'maplike' in promiseFound:
                         promiseCall = 'promiseToFuture<dynamic>'
                         promiseType = 'Future'
-                    elif promiseFound['type'] == 'dictionary':
+                    elif paramType == 'dictionary':
                         # It's a dictionary so return as a Map.
                         promiseCall = 'promiseToFutureAsMap'
                         output_conversion = self._OutputConversion("Dictionary",
@@ -1505,15 +1587,18 @@
                             else ''
                         promiseType = 'Future<Map<String, dynamic>' + \
                             nullability + '>'
-                    else:
-                        paramType = promiseFound['type']
+                    elif paramType:
                         promiseCall = 'promiseToFuture<%s>' % paramType
                         promiseType = 'Future<%s>' % paramType
 
+                    if 'creates' in promiseFound:
+                        createsType = promiseFound['creates']
+                        type_description = 'creates:%s;' % createsType
+
                 if attribute.type.nullable:
                     promiseType += '?'
 
-                template = '\n  $RENAME$(ANNOTATIONS)$TYPE get $NAME => $PROMISE_CALL(JS("", "#.$NAME", this));\n'
+                template = '\n  $RENAME$(ANNOTATIONS)$TYPE get $NAME => $PROMISE_CALL(JS("$TYPE_DESC", "#.$NAME", this));\n'
 
                 self._members_emitter.Emit(
                     template,
@@ -1521,7 +1606,8 @@
                     ANNOTATIONS=metadata,
                     TYPE=promiseType,
                     PROMISE_CALL=promiseCall,
-                    NAME=html_name)
+                    TYPE_DESC=type_description,
+                    NAME=html_name,)
             else:
                 # Need to use a getter for list.length properties so we can
                 # add a setter which throws an exception, satisfying List
@@ -1733,11 +1819,12 @@
         return resultType
 
     def _zeroArgs(self, argsNames):
-        return 'JS("", "#.$JSNAME()", this)'
+        return 'JS("$TYPE_DESC", "#.$JSNAME()", this)'
 
     def _manyArgs(self, numberArgs, argsNames):
         argsPound = "#" if numberArgs == 1 else ("#, " * numberArgs)[:-2]
-        return '    JS("", "#.$JSNAME(%s)", this, %s)' % (argsPound, argsNames)
+        template = '    JS("$TYPE_DESC", "#.$JSNAME(%s)", this, %s)'
+        return template % (argsPound, argsNames)
 
     """ If argument conversionsMapToDictionary is a list first entry is argument
       name and second entry signals if argument is optional (True). """
@@ -1812,13 +1899,14 @@
             promiseFound = _GetPromiseOperationType(lookupOp)
             promiseType = 'Future'
             promiseCall = 'promiseToFuture'
+            type_description = ''
             if promiseFound is not (None):
-                paramType = promiseFound['type']
+                paramType = promiseFound.get('type')
                 if 'maplike' in promiseFound:
                     if paramType == 'dictionary':
                         promiseCall = 'promiseToFuture<dynamic>'
                         promiseType = 'Future'
-                    else:
+                    elif paramType:
                         promiseCall = 'promiseToFuture<%s>' % paramType
                         promiseType = 'Future<%s>' % paramType
                 elif paramType == 'dictionary':
@@ -1830,10 +1918,14 @@
                         else ''
                     promiseType = 'Future<Map<String, dynamic>' + \
                         nullability + '>'
-                else:
+                elif paramType:
                     promiseCall = 'promiseToFuture<%s>' % paramType
                     promiseType = 'Future<%s>' % paramType
 
+                if 'creates' in promiseFound:
+                    createsType = promiseFound['creates']
+                    type_description = 'creates:%s;' % createsType
+
             argsNames = info.ParametersAsArgumentList()
             dictionary_argument = info.dictionaryArgumentName()
             codeTemplate = self._promiseToFutureCode(argsNames,
@@ -1851,6 +1943,7 @@
                 TYPE=promiseType,
                 PROMISE_CALL=promiseCall,
                 NAME=html_name,
+                TYPE_DESC=type_description,
                 JSNAME=info.declared_name,
                 PARAMS=info.ParametersAsDeclaration(self._NarrowInputType,
                                                     force_optional))
diff --git a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
index f7f535e..dc05346 100644
--- a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
@@ -70,7 +70,7 @@
  * and where both the keys and the values are strings.
  *
  * * [dart:web_sql]&mdash;a database that can be queried with SQL.
- * 
+ *
  * MDN provides [API
  * documentation](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API).
  *