diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 76aed36..66d9ee6 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -229,6 +229,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "dart2wasm",
+      "rootUri": "../pkg/dart2wasm",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "dart_internal",
       "rootUri": "../pkg/dart_internal",
       "packageUri": "lib/",
@@ -781,6 +787,12 @@
       "languageVersion": "2.12"
     },
     {
+      "name": "wasm_builder",
+      "rootUri": "../pkg/wasm_builder",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
+    },
+    {
       "name": "watcher",
       "rootUri": "../third_party/pkg/watcher",
       "packageUri": "lib/",
diff --git a/.packages b/.packages
index e8855d6..38ab4a9 100644
--- a/.packages
+++ b/.packages
@@ -33,6 +33,7 @@
 dart2js_runtime_metrics:pkg/dart2js_runtime_metrics/lib
 dart2js_tools:pkg/dart2js_tools/lib
 dart2native:pkg/dart2native/lib
+dart2wasm:pkg/dart2wasm/lib
 dart_internal:pkg/dart_internal/lib
 dart_style:third_party/pkg_tested/dart_style/lib
 dartdev:pkg/dartdev/lib
@@ -117,6 +118,7 @@
 vm:pkg/vm/lib
 vm_service:pkg/vm_service/lib
 vm_snapshot_analysis:pkg/vm_snapshot_analysis/lib
+wasm_builder:pkg/wasm_builder/lib
 watcher:third_party/pkg/watcher/lib
 webdriver:third_party/pkg/webdriver/lib
 webkit_inspection_protocol:third_party/pkg/webkit_inspection_protocol/lib
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart
index 63fd51c..35a6386 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/scanner.dart
@@ -72,7 +72,7 @@
     bool includeComments: false,
     LanguageVersionChanged? languageVersionChanged}) {
   if (bytes.last != 0) {
-    throw new ArgumentError("[bytes]: the last byte must be null.");
+    throw new ArgumentError("[bytes]: the last byte must be 0.");
   }
   Scanner scanner = new Utf8BytesScanner(bytes,
       configuration: configuration,
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
index 896c670..a1bbadb 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_generation.dart
@@ -65,13 +65,13 @@
     Map<Id, Map<String, IdValue>> idValuePerId = idValuePerUri[uri] ?? {};
     Map<Id, Map<String, ActualData<T>>> actualDataPerId =
         actualDataPerUri[uri] ?? {};
-    AnnotatedCode code = annotatedCode[uri]!;
-    assert(
-        // ignore: unnecessary_null_comparison
-        code != null, "No annotated code for ${uri} in ${annotatedCode.keys}");
-    result[uri] = _computeAnnotations(code, expectedMaps.keys, actualMarkers,
+    AnnotatedCode? code = annotatedCode[uri];
+    if (code != null) {
+      // Annotations are not computed from synthesized code.
+      result[uri] = _computeAnnotations(code, expectedMaps.keys, actualMarkers,
         idValuePerId, actualDataPerId, dataInterpreter,
         sortMarkers: false, createDiff: createDiff, forceUpdate: forceUpdate);
+    }
   }
   return result;
 }
diff --git a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
index 68ad3ab..ca35c17 100644
--- a/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/testing/id_testing.dart
@@ -771,7 +771,9 @@
   List<FileSystemEntity> entities = dataDir
       .listSync()
       .where((entity) =>
-          !entity.path.endsWith('~') && !entity.path.endsWith('marker.options'))
+          !entity.path.endsWith('~') &&
+          !entity.path.endsWith('marker.options') &&
+          !entity.path.endsWith('.expect'))
       .toList();
   if (shards > 1) {
     entities.sort((a, b) => getTestName(a).compareTo(getTestName(b)));
diff --git a/pkg/dart2wasm/bin/dart2wasm.dart b/pkg/dart2wasm/bin/dart2wasm.dart
new file mode 100644
index 0000000..10f1750
--- /dev/null
+++ b/pkg/dart2wasm/bin/dart2wasm.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2022, 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 'dart:io';
+import 'dart:typed_data';
+
+import 'package:front_end/src/api_unstable/vm.dart'
+    show printDiagnosticMessage, resolveInputUri;
+
+import 'package:dart2wasm/compile.dart';
+import 'package:dart2wasm/translator.dart';
+
+final Map<String, void Function(TranslatorOptions, bool)> boolOptionMap = {
+  "export-all": (o, value) => o.exportAll = value,
+  "inlining": (o, value) => o.inlining = value,
+  "lazy-constants": (o, value) => o.lazyConstants = value,
+  "local-nullability": (o, value) => o.localNullability = value,
+  "name-section": (o, value) => o.nameSection = value,
+  "nominal-types": (o, value) => o.nominalTypes = value,
+  "parameter-nullability": (o, value) => o.parameterNullability = value,
+  "polymorphic-specialization": (o, value) =>
+      o.polymorphicSpecialization = value,
+  "print-kernel": (o, value) => o.printKernel = value,
+  "print-wasm": (o, value) => o.printWasm = value,
+  "runtime-types": (o, value) => o.runtimeTypes = value,
+  "string-data-segments": (o, value) => o.stringDataSegments = value,
+};
+final Map<String, void Function(TranslatorOptions, int)> intOptionMap = {
+  "watch": (o, value) => (o.watchPoints ??= []).add(value),
+};
+
+Never usage(String message) {
+  print("Usage: dart2wasm [<options>] <infile.dart> <outfile.wasm>");
+  print("");
+  print("Options:");
+  print("  --dart-sdk=<path>");
+  print("");
+  for (String option in boolOptionMap.keys) {
+    print("  --[no-]$option");
+  }
+  print("");
+  for (String option in intOptionMap.keys) {
+    print("  --$option <value>");
+  }
+  print("");
+
+  throw message;
+}
+
+Future<int> main(List<String> args) async {
+  Uri sdkPath = Platform.script.resolve("../../../sdk");
+  TranslatorOptions options = TranslatorOptions();
+  List<String> nonOptions = [];
+  void Function(TranslatorOptions, int)? intOptionFun = null;
+  for (String arg in args) {
+    if (intOptionFun != null) {
+      intOptionFun(options, int.parse(arg));
+      intOptionFun = null;
+    } else if (arg.startsWith("--dart-sdk=")) {
+      String path = arg.substring("--dart-sdk=".length);
+      sdkPath = Uri.file(Directory(path).absolute.path);
+    } else if (arg.startsWith("--no-")) {
+      var optionFun = boolOptionMap[arg.substring(5)];
+      if (optionFun == null) usage("Unknown option $arg");
+      optionFun(options, false);
+    } else if (arg.startsWith("--")) {
+      var optionFun = boolOptionMap[arg.substring(2)];
+      if (optionFun != null) {
+        optionFun(options, true);
+      } else {
+        intOptionFun = intOptionMap[arg.substring(2)];
+        if (intOptionFun == null) usage("Unknown option $arg");
+      }
+    } else {
+      nonOptions.add(arg);
+    }
+  }
+  if (intOptionFun != null) {
+    usage("Missing argument to ${args.last}");
+  }
+
+  if (nonOptions.length != 2) usage("Requires two file arguments");
+  String input = nonOptions[0];
+  String output = nonOptions[1];
+  Uri mainUri = resolveInputUri(input);
+
+  Uint8List? module = await compileToModule(mainUri, sdkPath, options,
+      (message) => printDiagnosticMessage(message, print));
+
+  if (module == null) {
+    exitCode = 1;
+    return exitCode;
+  }
+
+  await File(output).writeAsBytes(module);
+
+  return 0;
+}
diff --git a/pkg/dart2wasm/bin/run_wasm.js b/pkg/dart2wasm/bin/run_wasm.js
new file mode 100644
index 0000000..08a6d92
--- /dev/null
+++ b/pkg/dart2wasm/bin/run_wasm.js
@@ -0,0 +1,63 @@
+// Copyright (c) 2022, 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.
+//
+// Runner V8 script for testing dart2wasm, takes ".wasm" file as argument.
+// Run as follows:
+//
+// $> d8 --experimental-wasm-gc --wasm-gc-js-interop run_wasm.js -- <file_name>.wasm
+
+function stringFromDartString(string) {
+    var length = inst.exports.$stringLength(string);
+    var array = new Array(length);
+    for (var i = 0; i < length; i++) {
+        array[i] = inst.exports.$stringRead(string, i);
+    }
+    return String.fromCharCode(...array);
+}
+
+function stringToDartString(string) {
+    var length = string.length;
+    var range = 0;
+    for (var i = 0; i < length; i++) {
+        range |= string.codePointAt(i);
+    }
+    if (range < 256) {
+        var dartString = inst.exports.$stringAllocate1(length);
+        for (var i = 0; i < length; i++) {
+            inst.exports.$stringWrite1(dartString, i, string.codePointAt(i));
+        }
+        return dartString;
+    } else {
+        var dartString = inst.exports.$stringAllocate2(length);
+        for (var i = 0; i < length; i++) {
+            inst.exports.$stringWrite2(dartString, i, string.codePointAt(i));
+        }
+        return dartString;
+    }
+}
+
+// Imports for printing and event loop
+var dart2wasm = {
+    printToConsole: function(string) {
+        console.log(stringFromDartString(string))
+    },
+    scheduleCallback: function(milliseconds, closure) {
+        setTimeout(function() {
+            inst.exports.$call0(closure);
+        }, milliseconds);
+    }
+};
+
+// Create a Wasm module from the binary wasm file.
+var bytes = readbuffer(arguments[0]);
+var module = new WebAssembly.Module(bytes);
+
+// Instantiate the Wasm module, importing from the global scope.
+var importObject = (typeof window !== 'undefined')
+    ? window
+    : Realm.global(Realm.current());
+var inst = new WebAssembly.Instance(module, importObject);
+
+var result = inst.exports.main();
+if (result) console.log(result);
diff --git a/pkg/dart2wasm/dart2wasm.md b/pkg/dart2wasm/dart2wasm.md
new file mode 100644
index 0000000..8dc3203
--- /dev/null
+++ b/pkg/dart2wasm/dart2wasm.md
@@ -0,0 +1,65 @@
+## Running dart2wasm
+
+You don't need to build the Dart SDK to run dart2wasm, as long as you have a Dart SDK installed.
+
+To compile a Dart file to Wasm, run:
+
+`dart --enable-asserts pkg/dart2wasm/bin/dart2wasm.dart` *options* *infile*`.dart` *outfile*`.wasm`
+
+where *options* include:
+
+| Option                                  | Default | Description |
+| --------------------------------------- | ------- | ----------- |
+| `--dart-sdk=`*path*                     | relative to script | The location of the `sdk` directory inside the Dart SDK, containing the core library sources.
+| `--`[`no-`]`export-all`                 | no      | Export all functions; otherwise, just export `main`.
+| `--`[`no-`]`inlining`                   | no      | Inline small functions.
+| `--`[`no-`]`lazy-constants`             | no      | Instantiate constants lazily.
+| `--`[`no-`]`local-nullability`          | no      | Use non-nullable types for non-nullable locals and temporaries.
+| `--`[`no-`]`name-section`               | yes     | Emit Name Section with function names.
+| `--`[`no-`]`nominal-types`              | no      | Emit experimental nominal types.
+| `--`[`no-`]`parameter-nullability`      | yes     | Use non-nullable types for non-nullable parameters and return values.
+| `--`[`no-`]`polymorphic-specialization` | no      | Do virtual calls by switching on the class ID instead of using `call_indirect`.
+| `--`[`no-`]`print-kernel`               | no      | Print IR for each function before compiling it.
+| `--`[`no-`]`print-wasm`                 | no      | Print Wasm instructions of each compiled function.
+| `--`[`no-`]`runtime-types`              | yes     | Use RTTs for allocations and casts.
+| `--`[`no-`]`string-data-segments`       | no      | Use experimental array init from data segment for string constants.
+| `--watch` *offset*                      |         | Print stack trace leading to the byte at offset *offset* in the `.wasm` output file. Can be specified multiple times.
+
+The resulting `.wasm` file can be run with:
+
+`d8 --experimental-wasm-gc --wasm-gc-js-interop pkg/dart2wasm/bin/run_wasm.js -- `*outfile*`.wasm`
+
+## Imports and exports
+
+To import a function, declare it as a global, external function and mark it with a `wasm:import` pragma indicating the imported name (which must be two identifiers separated by a dot):
+```dart
+@pragma("wasm:import", "foo.bar")
+external void fooBar(Object object);
+```
+which will call `foo.bar` on the host side:
+```javascript
+var foo = {
+    bar: function(object) { /* implementation here */ }
+};
+```
+To export a function, mark it with a `wasm:export` pragma:
+```dart
+@pragma("wasm:export")
+void foo(double x) { /* implementation here */  }
+
+@pragma("wasm:export", "baz")
+void bar(double x) { /* implementation here */  }
+```
+With the Wasm module instance in `inst`, these can be called as:
+```javascript
+inst.exports.foo(1);
+inst.exports.baz(2);
+```
+
+### Types to use for interop
+
+In the signatures of imported and exported functions, use the following types:
+
+- For numbers, use `double`.
+- For Dart objects, use the corresponding Dart type. The fields of the underlying representation can be accessed on the JS side as `.$field0`, `.$field1` etc., but there is currently no defined way of finding the field index of a particular Dart field, so this mechanism is mainly useful for special objects with known layout.
+- For JS objects, use the `WasmAnyRef` type (or `WasmAnyRef?` as applicable) from the `dart:wasm` package. These can be passed around and stored as opaque values on the Dart side.
diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart
new file mode 100644
index 0000000..54037e0
--- /dev/null
+++ b/pkg/dart2wasm/lib/class_info.dart
@@ -0,0 +1,377 @@
+// Copyright (c) 2022, 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 'dart:math';
+
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// Wasm struct field indices for fields that are accessed explicitly from Wasm
+/// code, e.g. in intrinsics.
+///
+/// The values are validated by asserts, typically either through
+/// [ClassInfo.addField] (for manually added fields) or by a line in
+/// [FieldIndex.validate] (for fields declared in Dart code).
+class FieldIndex {
+  static const classId = 0;
+  static const boxValue = 1;
+  static const identityHash = 1;
+  static const stringArray = 2;
+  static const closureContext = 2;
+  static const closureFunction = 3;
+  static const typedListBaseLength = 2;
+  static const typedListArray = 3;
+  static const typedListViewTypedData = 3;
+  static const typedListViewOffsetInBytes = 4;
+  static const byteDataViewLength = 2;
+  static const byteDataViewTypedData = 3;
+  static const byteDataViewOffsetInBytes = 4;
+
+  static void validate(Translator translator) {
+    void check(Class cls, String name, int expectedIndex) {
+      assert(
+          translator.fieldIndex[
+                  cls.fields.firstWhere((f) => f.name.text == name)] ==
+              expectedIndex,
+          "Unexpected field index for ${cls.name}.$name");
+    }
+
+    check(translator.boxedBoolClass, "value", FieldIndex.boxValue);
+    check(translator.boxedIntClass, "value", FieldIndex.boxValue);
+    check(translator.boxedDoubleClass, "value", FieldIndex.boxValue);
+    check(translator.oneByteStringClass, "_array", FieldIndex.stringArray);
+    check(translator.twoByteStringClass, "_array", FieldIndex.stringArray);
+    check(translator.functionClass, "context", FieldIndex.closureContext);
+  }
+}
+
+const int initialIdentityHash = 0;
+
+/// Information about the Wasm representation for a class.
+class ClassInfo {
+  /// The Dart class that this info corresponds to. The top type does not have
+  /// an associated Dart class.
+  final Class? cls;
+
+  /// The Class ID of this class, stored in every instance of the class.
+  final int classId;
+
+  /// Depth of this class in the Wasm type hierarchy.
+  final int depth;
+
+  /// The Wasm struct used to represent instances of this class. A class will
+  /// sometimes use the same struct as its superclass.
+  final w.StructType struct;
+
+  /// Wasm global containing the RTT for this class.
+  late final w.DefinedGlobal rtt;
+
+  /// The superclass for this class. This will usually be the Dart superclass,
+  /// but there are a few exceptions, where the Wasm type hierarchy does not
+  /// follow the Dart class hierarchy.
+  final ClassInfo? superInfo;
+
+  /// For every type parameter which is directly mapped to a type parameter in
+  /// the superclass, this contains the corresponding superclass type
+  /// parameter. These will reuse the corresponding type parameter field of
+  /// the superclass.
+  final Map<TypeParameter, TypeParameter> typeParameterMatch;
+
+  /// The class whose struct is used as the type for variables of this type.
+  /// This is a type which is a superclass of all subtypes of this type.
+  late ClassInfo repr;
+
+  /// All classes which implement this class. This is used to compute `repr`.
+  final List<ClassInfo> implementedBy = [];
+
+  late final w.RefType nullableType = w.RefType.def(struct, nullable: true);
+  late final w.RefType nonNullableType = w.RefType.def(struct, nullable: false);
+
+  w.RefType typeWithNullability(bool nullable) =>
+      nullable ? nullableType : nonNullableType;
+
+  ClassInfo(this.cls, this.classId, this.depth, this.struct, this.superInfo,
+      ClassInfoCollector collector,
+      {this.typeParameterMatch = const {}}) {
+    if (collector.options.useRttGlobals) {
+      rtt = collector.makeRtt(struct, superInfo);
+    }
+    implementedBy.add(this);
+  }
+
+  void addField(w.FieldType fieldType, [int? expectedIndex]) {
+    assert(expectedIndex == null || expectedIndex == struct.fields.length);
+    struct.fields.add(fieldType);
+  }
+}
+
+ClassInfo upperBound(Iterable<ClassInfo> classes) {
+  while (classes.length > 1) {
+    Set<ClassInfo> newClasses = {};
+    int minDepth = 999999999;
+    int maxDepth = 0;
+    for (ClassInfo info in classes) {
+      minDepth = min(minDepth, info.depth);
+      maxDepth = max(maxDepth, info.depth);
+    }
+    int targetDepth = minDepth == maxDepth ? minDepth - 1 : minDepth;
+    for (ClassInfo info in classes) {
+      while (info.depth > targetDepth) {
+        info = info.superInfo!;
+      }
+      newClasses.add(info);
+    }
+    classes = newClasses;
+  }
+  return classes.single;
+}
+
+/// Constructs the Wasm type hierarchy.
+class ClassInfoCollector {
+  final Translator translator;
+  int nextClassId = 0;
+  late final ClassInfo topInfo;
+
+  late final w.FieldType typeType =
+      w.FieldType(translator.classInfo[translator.typeClass]!.nullableType);
+
+  ClassInfoCollector(this.translator);
+
+  w.Module get m => translator.m;
+
+  TranslatorOptions get options => translator.options;
+
+  w.DefinedGlobal makeRtt(w.StructType struct, ClassInfo? superInfo) {
+    assert(options.useRttGlobals);
+    int depth = superInfo != null ? superInfo.depth + 1 : 0;
+    final w.DefinedGlobal rtt =
+        m.addGlobal(w.GlobalType(w.Rtt(struct, depth), mutable: false));
+    final w.Instructions b = rtt.initializer;
+    if (superInfo != null) {
+      b.global_get(superInfo.rtt);
+      b.rtt_sub(struct);
+    } else {
+      b.rtt_canon(struct);
+    }
+    b.end();
+    return rtt;
+  }
+
+  void initializeTop() {
+    final w.StructType struct = translator.structType("#Top");
+    topInfo = ClassInfo(null, nextClassId++, 0, struct, null, this);
+    translator.classes.add(topInfo);
+    translator.classForHeapType[struct] = topInfo;
+  }
+
+  void initialize(Class cls) {
+    ClassInfo? info = translator.classInfo[cls];
+    if (info == null) {
+      Class? superclass = cls.superclass;
+      if (superclass == null) {
+        ClassInfo superInfo = topInfo;
+        final w.StructType struct =
+            translator.structType(cls.name, superType: superInfo.struct);
+        info = ClassInfo(
+            cls, nextClassId++, superInfo.depth + 1, struct, superInfo, this);
+        // Mark Top type as implementing Object to force the representation
+        // type of Object to be Top.
+        info.implementedBy.add(topInfo);
+      } else {
+        // Recursively initialize all supertypes before initializing this class.
+        initialize(superclass);
+        for (Supertype interface in cls.implementedTypes) {
+          initialize(interface.classNode);
+        }
+
+        // In the Wasm type hierarchy, Object, bool and num sit directly below
+        // the Top type. The implementation classes (_StringBase, _Type and the
+        // box classes) sit directly below the public classes they implement.
+        // All other classes sit below their superclass.
+        ClassInfo superInfo = cls == translator.coreTypes.boolClass ||
+                cls == translator.coreTypes.numClass
+            ? topInfo
+            : cls == translator.stringBaseClass ||
+                    cls == translator.typeClass ||
+                    translator.boxedClasses.values.contains(cls)
+                ? translator.classInfo[cls.implementedTypes.single.classNode]!
+                : translator.classInfo[superclass]!;
+
+        // Figure out which type parameters can reuse a type parameter field of
+        // the superclass.
+        Map<TypeParameter, TypeParameter> typeParameterMatch = {};
+        if (cls.typeParameters.isNotEmpty) {
+          Supertype supertype = cls.superclass == superInfo.cls
+              ? cls.supertype!
+              : cls.implementedTypes.single;
+          for (TypeParameter parameter in cls.typeParameters) {
+            for (int i = 0; i < supertype.typeArguments.length; i++) {
+              DartType arg = supertype.typeArguments[i];
+              if (arg is TypeParameterType && arg.parameter == parameter) {
+                typeParameterMatch[parameter] =
+                    superInfo.cls!.typeParameters[i];
+                break;
+              }
+            }
+          }
+        }
+
+        // A class can reuse the Wasm struct of the superclass if it doesn't
+        // declare any Wasm fields of its own. This is the case when three
+        // conditions are met:
+        //   1. All type parameters can reuse a type parameter field of the
+        //      superclass.
+        //   2. The class declares no Dart fields of its own.
+        //   3. The class is not a special class that contains hidden fields.
+        bool canReuseSuperStruct =
+            typeParameterMatch.length == cls.typeParameters.length &&
+                cls.fields.where((f) => f.isInstanceMember).isEmpty &&
+                cls != translator.typedListBaseClass &&
+                cls != translator.typedListClass &&
+                cls != translator.typedListViewClass &&
+                cls != translator.byteDataViewClass;
+        w.StructType struct = canReuseSuperStruct
+            ? superInfo.struct
+            : translator.structType(cls.name, superType: superInfo.struct);
+        info = ClassInfo(
+            cls, nextClassId++, superInfo.depth + 1, struct, superInfo, this,
+            typeParameterMatch: typeParameterMatch);
+
+        // Mark all interfaces as being implemented by this class. This is
+        // needed to calculate representation types.
+        for (Supertype interface in cls.implementedTypes) {
+          ClassInfo? interfaceInfo = translator.classInfo[interface.classNode];
+          while (interfaceInfo != null) {
+            interfaceInfo.implementedBy.add(info);
+            interfaceInfo = interfaceInfo.superInfo;
+          }
+        }
+      }
+      translator.classes.add(info);
+      translator.classInfo[cls] = info;
+      translator.classForHeapType.putIfAbsent(info.struct, () => info!);
+    }
+  }
+
+  void computeRepresentation(ClassInfo info) {
+    info.repr = upperBound(info.implementedBy);
+  }
+
+  void generateFields(ClassInfo info) {
+    ClassInfo? superInfo = info.superInfo;
+    if (superInfo == null) {
+      // Top - add class id field
+      info.addField(w.FieldType(w.NumType.i32), FieldIndex.classId);
+    } else if (info.struct != superInfo.struct) {
+      // Copy fields from superclass
+      for (w.FieldType fieldType in superInfo.struct.fields) {
+        info.addField(fieldType);
+      }
+      if (info.cls!.superclass == null) {
+        // Object - add identity hash code field
+        info.addField(w.FieldType(w.NumType.i32), FieldIndex.identityHash);
+      }
+      // Add fields for type variables
+      for (TypeParameter parameter in info.cls!.typeParameters) {
+        TypeParameter? match = info.typeParameterMatch[parameter];
+        if (match != null) {
+          // Reuse supertype type variable
+          translator.typeParameterIndex[parameter] =
+              translator.typeParameterIndex[match]!;
+        } else {
+          translator.typeParameterIndex[parameter] = info.struct.fields.length;
+          info.addField(typeType);
+        }
+      }
+      // Add fields for Dart instance fields
+      for (Field field in info.cls!.fields) {
+        if (field.isInstanceMember) {
+          w.ValueType wasmType = translator.translateType(field.type);
+          // TODO(askesc): Generalize this check for finer nullability control
+          if (wasmType != w.RefType.data()) {
+            wasmType = wasmType.withNullability(true);
+          }
+          translator.fieldIndex[field] = info.struct.fields.length;
+          info.addField(w.FieldType(wasmType));
+        }
+      }
+    } else {
+      for (TypeParameter parameter in info.cls!.typeParameters) {
+        // Reuse supertype type variable
+        translator.typeParameterIndex[parameter] =
+            translator.typeParameterIndex[info.typeParameterMatch[parameter]]!;
+      }
+    }
+  }
+
+  void collect() {
+    // Create class info and Wasm structs for all classes.
+    initializeTop();
+    for (Library library in translator.component.libraries) {
+      for (Class cls in library.classes) {
+        initialize(cls);
+      }
+    }
+
+    // For each class, compute which Wasm struct should be used for the type of
+    // variables bearing that class as their Dart type. This is the struct
+    // corresponding to the least common supertype of all Dart classes
+    // implementing this class.
+    for (ClassInfo info in translator.classes) {
+      computeRepresentation(info);
+    }
+
+    // Now that the representation types for all classes have been computed,
+    // fill in the types of the fields in the generated Wasm structs.
+    for (ClassInfo info in translator.classes) {
+      generateFields(info);
+    }
+
+    // Add hidden fields of typed_data classes.
+    addTypedDataFields();
+
+    // Validate that all internally used fields have the expected indices.
+    FieldIndex.validate(translator);
+  }
+
+  void addTypedDataFields() {
+    ClassInfo typedListBaseInfo =
+        translator.classInfo[translator.typedListBaseClass]!;
+    typedListBaseInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
+        FieldIndex.typedListBaseLength);
+
+    ClassInfo typedListInfo = translator.classInfo[translator.typedListClass]!;
+    typedListInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
+        FieldIndex.typedListBaseLength);
+    w.RefType bytesArrayType = w.RefType.def(
+        translator.wasmArrayType(w.PackedType.i8, "i8"),
+        nullable: false);
+    typedListInfo.addField(
+        w.FieldType(bytesArrayType, mutable: false), FieldIndex.typedListArray);
+
+    w.RefType typedListType =
+        w.RefType.def(typedListInfo.struct, nullable: false);
+
+    ClassInfo typedListViewInfo =
+        translator.classInfo[translator.typedListViewClass]!;
+    typedListViewInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
+        FieldIndex.typedListBaseLength);
+    typedListViewInfo.addField(w.FieldType(typedListType, mutable: false),
+        FieldIndex.typedListViewTypedData);
+    typedListViewInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
+        FieldIndex.typedListViewOffsetInBytes);
+
+    ClassInfo byteDataViewInfo =
+        translator.classInfo[translator.byteDataViewClass]!;
+    byteDataViewInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
+        FieldIndex.byteDataViewLength);
+    byteDataViewInfo.addField(w.FieldType(typedListType, mutable: false),
+        FieldIndex.byteDataViewTypedData);
+    byteDataViewInfo.addField(w.FieldType(w.NumType.i32, mutable: false),
+        FieldIndex.byteDataViewOffsetInBytes);
+  }
+}
diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart
new file mode 100644
index 0000000..cde1b4c
--- /dev/null
+++ b/pkg/dart2wasm/lib/closures.dart
@@ -0,0 +1,318 @@
+// Copyright (c) 2022, 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:dart2wasm/code_generator.dart';
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// A local function or function expression.
+class Lambda {
+  final FunctionNode functionNode;
+  final w.DefinedFunction function;
+
+  Lambda(this.functionNode, this.function);
+}
+
+/// The context for one or more closures, containing their captured variables.
+///
+/// Contexts can be nested, corresponding to the scopes covered by the contexts.
+/// Each local function, function expression or loop (`while`, `do`/`while` or
+/// `for`) gives rise to its own context nested inside the context of its
+/// surrounding scope. At runtime, each context has a reference to its parent
+/// context.
+///
+/// Closures corresponding to local functions or function expressions in the
+/// same scope share the same context. Thus, a closure can potentially keep more
+/// values alive than the ones captured by the closure itself.
+///
+/// A context may be empty (containing no captured variables), in which case it
+/// is skipped in the context parent chain and never allocated. A context can
+/// also be skipped if it only contains variables that are not in scope for the
+/// child context (and its descendants).
+class Context {
+  /// The node containing the scope covered by the context. This is either a
+  /// [FunctionNode] (for members, local functions and function expressions),
+  /// a [ForStatement], a [DoStatement] or a [WhileStatement].
+  final TreeNode owner;
+
+  /// The parent of this context, corresponding to the lexically enclosing
+  /// owner. This is null if the context is a member context, or if all contexts
+  /// in the parent chain are skipped.
+  final Context? parent;
+
+  /// The variables captured by this context.
+  final List<VariableDeclaration> variables = [];
+
+  /// Whether this context contains a captured `this`. Only member contexts can.
+  bool containsThis = false;
+
+  /// The Wasm struct representing this context at runtime.
+  late final w.StructType struct;
+
+  /// The local variable currently pointing to this context. Used during code
+  /// generation.
+  late w.Local currentLocal;
+
+  bool get isEmpty => variables.isEmpty && !containsThis;
+
+  int get parentFieldIndex {
+    assert(parent != null);
+    return 0;
+  }
+
+  int get thisFieldIndex {
+    assert(containsThis);
+    return 0;
+  }
+
+  Context(this.owner, this.parent);
+}
+
+/// A captured variable.
+class Capture {
+  final VariableDeclaration variable;
+  late final Context context;
+  late final int fieldIndex;
+  bool written = false;
+
+  Capture(this.variable);
+
+  w.ValueType get type => context.struct.fields[fieldIndex].type.unpacked;
+}
+
+/// Compiler passes to find all captured variables and construct the context
+/// tree for a member.
+class Closures {
+  final CodeGenerator codeGen;
+  final Map<VariableDeclaration, Capture> captures = {};
+  bool isThisCaptured = false;
+  final Map<FunctionNode, Lambda> lambdas = {};
+  final Map<TreeNode, Context> contexts = {};
+  final Set<FunctionDeclaration> closurizedFunctions = {};
+
+  Closures(this.codeGen);
+
+  Translator get translator => codeGen.translator;
+
+  void findCaptures(Member member) {
+    var find = CaptureFinder(this, member);
+    if (member is Constructor) {
+      Class cls = member.enclosingClass;
+      for (Field field in cls.fields) {
+        if (field.isInstanceMember && field.initializer != null) {
+          field.initializer!.accept(find);
+        }
+      }
+    }
+    member.accept(find);
+  }
+
+  void collectContexts(TreeNode node, {TreeNode? container}) {
+    if (captures.isNotEmpty || isThisCaptured) {
+      node.accept(ContextCollector(this, container));
+    }
+  }
+
+  void buildContexts() {
+    // Make struct definitions
+    for (Context context in contexts.values) {
+      if (!context.isEmpty) {
+        context.struct = translator.structType("<context>");
+      }
+    }
+
+    // Build object layouts
+    for (Context context in contexts.values) {
+      if (!context.isEmpty) {
+        w.StructType struct = context.struct;
+        if (context.parent != null) {
+          assert(!context.containsThis);
+          struct.fields.add(w.FieldType(
+              w.RefType.def(context.parent!.struct, nullable: true)));
+        }
+        if (context.containsThis) {
+          struct.fields.add(w.FieldType(
+              codeGen.preciseThisLocal!.type.withNullability(true)));
+        }
+        for (VariableDeclaration variable in context.variables) {
+          int index = struct.fields.length;
+          struct.fields.add(w.FieldType(
+              translator.translateType(variable.type).withNullability(true)));
+          captures[variable]!.fieldIndex = index;
+        }
+      }
+    }
+  }
+}
+
+class CaptureFinder extends RecursiveVisitor {
+  final Closures closures;
+  final Member member;
+  final Map<VariableDeclaration, int> variableDepth = {};
+  int depth = 0;
+
+  CaptureFinder(this.closures, this.member);
+
+  Translator get translator => closures.translator;
+
+  @override
+  void visitAssertStatement(AssertStatement node) {}
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    if (depth > 0) {
+      variableDepth[node] = depth;
+    }
+    super.visitVariableDeclaration(node);
+  }
+
+  void _visitVariableUse(VariableDeclaration variable) {
+    int declDepth = variableDepth[variable] ?? 0;
+    assert(declDepth <= depth);
+    if (declDepth < depth) {
+      closures.captures[variable] = Capture(variable);
+    } else if (variable.parent is FunctionDeclaration) {
+      closures.closurizedFunctions.add(variable.parent as FunctionDeclaration);
+    }
+  }
+
+  @override
+  void visitVariableGet(VariableGet node) {
+    _visitVariableUse(node.variable);
+    super.visitVariableGet(node);
+  }
+
+  @override
+  void visitVariableSet(VariableSet node) {
+    _visitVariableUse(node.variable);
+    super.visitVariableSet(node);
+  }
+
+  void _visitThis() {
+    if (depth > 0) {
+      closures.isThisCaptured = true;
+    }
+  }
+
+  @override
+  void visitThisExpression(ThisExpression node) {
+    _visitThis();
+  }
+
+  @override
+  void visitSuperMethodInvocation(SuperMethodInvocation node) {
+    _visitThis();
+    super.visitSuperMethodInvocation(node);
+  }
+
+  @override
+  void visitTypeParameterType(TypeParameterType node) {
+    if (node.parameter.parent == member.enclosingClass) {
+      _visitThis();
+    }
+  }
+
+  void _visitLambda(FunctionNode node) {
+    if (node.positionalParameters.length != node.requiredParameterCount ||
+        node.namedParameters.isNotEmpty) {
+      throw "Not supported: Optional parameters for "
+          "function expression or local function at ${node.location}";
+    }
+    int parameterCount = node.requiredParameterCount;
+    w.FunctionType type = translator.closureFunctionType(parameterCount);
+    w.DefinedFunction function =
+        translator.m.addFunction(type, "$member (closure)");
+    closures.lambdas[node] = Lambda(node, function);
+
+    depth++;
+    node.visitChildren(this);
+    depth--;
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    _visitLambda(node.function);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    // Variable is in outer scope
+    node.variable.accept(this);
+    _visitLambda(node.function);
+  }
+}
+
+class ContextCollector extends RecursiveVisitor {
+  final Closures closures;
+  Context? currentContext;
+
+  ContextCollector(this.closures, TreeNode? container) {
+    if (container != null) {
+      currentContext = closures.contexts[container]!;
+    }
+  }
+
+  @override
+  void visitAssertStatement(AssertStatement node) {}
+
+  void _newContext(TreeNode node) {
+    bool outerMost = currentContext == null;
+    Context? oldContext = currentContext;
+    Context? parent = currentContext;
+    while (parent != null && parent.isEmpty) parent = parent.parent;
+    currentContext = Context(node, parent);
+    if (closures.isThisCaptured && outerMost) {
+      currentContext!.containsThis = true;
+    }
+    closures.contexts[node] = currentContext!;
+    node.visitChildren(this);
+    currentContext = oldContext;
+  }
+
+  @override
+  void visitConstructor(Constructor node) {
+    node.function.accept(this);
+    currentContext = closures.contexts[node.function]!;
+    visitList(node.initializers, this);
+  }
+
+  @override
+  void visitFunctionNode(FunctionNode node) {
+    _newContext(node);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    _newContext(node);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    _newContext(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    _newContext(node);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    Capture? capture = closures.captures[node];
+    if (capture != null) {
+      currentContext!.variables.add(node);
+      capture.context = currentContext!;
+    }
+    super.visitVariableDeclaration(node);
+  }
+
+  @override
+  void visitVariableSet(VariableSet node) {
+    closures.captures[node.variable]?.written = true;
+    super.visitVariableSet(node);
+  }
+}
diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart
new file mode 100644
index 0000000..d4ef423
--- /dev/null
+++ b/pkg/dart2wasm/lib/code_generator.dart
@@ -0,0 +1,1940 @@
+// Copyright (c) 2022, 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:dart2wasm/class_info.dart';
+import 'package:dart2wasm/closures.dart';
+import 'package:dart2wasm/dispatch_table.dart';
+import 'package:dart2wasm/intrinsics.dart';
+import 'package:dart2wasm/param_info.dart';
+import 'package:dart2wasm/reference_extensions.dart';
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/type_environment.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// Main code generator for member bodies.
+///
+/// The [generate] method first collects all local functions and function
+/// expressions in the body and then generates code for the body. Code for the
+/// local functions and function expressions must be generated separately by
+/// calling the [generateLambda] method on all lambdas in [closures].
+///
+/// A new [CodeGenerator] object must be created for each new member or lambda.
+///
+/// Every visitor method for an expression takes in the Wasm type that it is
+/// expected to leave on the stack (or the special [voidMarker] to indicate that
+/// it should leave nothing). It returns what it actually left on the stack. The
+/// code generation for every expression or subexpression is done via the [wrap]
+/// method, which emits appropriate conversion code if the produced type is not
+/// a subtype of the expected type.
+class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
+    implements InitializerVisitor<void>, StatementVisitor<void> {
+  final Translator translator;
+  final w.DefinedFunction function;
+  final Reference reference;
+  late final List<w.Local> paramLocals;
+  final w.Label? returnLabel;
+
+  late final Intrinsifier intrinsifier;
+  late final StaticTypeContext typeContext;
+  late final w.Instructions b;
+
+  late final Closures closures;
+
+  final Map<VariableDeclaration, w.Local> locals = {};
+  w.Local? thisLocal;
+  w.Local? preciseThisLocal;
+  final Map<TypeParameter, w.Local> typeLocals = {};
+  final List<Statement> finalizers = [];
+  final Map<LabeledStatement, w.Label> labels = {};
+  final Map<SwitchCase, w.Label> switchLabels = {};
+
+  /// Create a code generator for a member or one of its lambdas.
+  ///
+  /// The [paramLocals] and [returnLabel] parameters can be used to generate
+  /// code for an inlined function by specifying the locals containing the
+  /// parameters (instead of the function inputs) and the label to jump to on
+  /// return (instead of emitting a `return` instruction).
+  CodeGenerator(this.translator, this.function, this.reference,
+      {List<w.Local>? paramLocals, this.returnLabel}) {
+    this.paramLocals = paramLocals ?? function.locals;
+    intrinsifier = Intrinsifier(this);
+    typeContext = StaticTypeContext(member, translator.typeEnvironment);
+    b = function.body;
+  }
+
+  Member get member => reference.asMember;
+
+  w.ValueType get returnType => translator
+      .outputOrVoid(returnLabel?.targetTypes ?? function.type.outputs);
+
+  TranslatorOptions get options => translator.options;
+
+  w.ValueType get voidMarker => translator.voidMarker;
+
+  w.ValueType translateType(DartType type) => translator.translateType(type);
+
+  w.Local addLocal(w.ValueType type) {
+    return function.addLocal(translator.typeForLocal(type));
+  }
+
+  DartType dartTypeOf(Expression exp) {
+    return exp.getStaticType(typeContext);
+  }
+
+  void _unimplemented(
+      TreeNode node, Object message, List<w.ValueType> expectedTypes) {
+    final text = "Not implemented: $message at ${node.location}";
+    print(text);
+    b.comment(text);
+    b.block(const [], expectedTypes);
+    b.unreachable();
+    b.end();
+  }
+
+  @override
+  void defaultInitializer(Initializer node) {
+    _unimplemented(node, node.runtimeType, const []);
+  }
+
+  @override
+  w.ValueType defaultExpression(Expression node, w.ValueType expectedType) {
+    _unimplemented(node, node.runtimeType, [expectedType]);
+    return expectedType;
+  }
+
+  @override
+  void defaultStatement(Statement node) {
+    _unimplemented(node, node.runtimeType, const []);
+  }
+
+  /// Generate code for the body of the member.
+  void generate() {
+    closures = Closures(this);
+
+    Member member = this.member;
+
+    if (reference.isTearOffReference) {
+      // Tear-off getter
+      w.DefinedFunction closureFunction =
+          translator.getTearOffFunction(member as Procedure);
+
+      int parameterCount = member.function.requiredParameterCount;
+      w.DefinedGlobal global = translator.makeFunctionRef(closureFunction);
+
+      ClassInfo info = translator.classInfo[translator.functionClass]!;
+      translator.functions.allocateClass(info.classId);
+
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.local_get(paramLocals[0]);
+      b.global_get(global);
+      translator.struct_new(b, parameterCount);
+      b.end();
+      return;
+    }
+
+    if (intrinsifier.generateMemberIntrinsic(
+        reference, function, paramLocals, returnLabel)) {
+      b.end();
+      return;
+    }
+
+    if (member.isExternal) {
+      final text =
+          "Unimplemented external member $member at ${member.location}";
+      print(text);
+      b.comment(text);
+      b.unreachable();
+      b.end();
+      return;
+    }
+
+    if (member is Field) {
+      if (member.isStatic) {
+        // Static field initializer function
+        assert(reference == member.fieldReference);
+        closures.findCaptures(member);
+        closures.collectContexts(member);
+        closures.buildContexts();
+
+        w.Global global = translator.globals.getGlobal(member);
+        w.Global? flag = translator.globals.getGlobalInitializedFlag(member);
+        wrap(member.initializer!, global.type.type);
+        b.global_set(global);
+        if (flag != null) {
+          b.i32_const(1);
+          b.global_set(flag);
+        }
+        b.global_get(global);
+        translator.convertType(
+            function, global.type.type, function.type.outputs.single);
+        b.end();
+        return;
+      }
+
+      // Implicit getter or setter
+      w.StructType struct =
+          translator.classInfo[member.enclosingClass!]!.struct;
+      int fieldIndex = translator.fieldIndex[member]!;
+      w.ValueType fieldType = struct.fields[fieldIndex].type.unpacked;
+
+      void getThis() {
+        w.Local thisLocal = paramLocals[0];
+        w.RefType structType = w.RefType.def(struct, nullable: true);
+        b.local_get(thisLocal);
+        translator.convertType(function, thisLocal.type, structType);
+      }
+
+      if (reference.isImplicitGetter) {
+        // Implicit getter
+        getThis();
+        b.struct_get(struct, fieldIndex);
+        translator.convertType(function, fieldType, returnType);
+      } else {
+        // Implicit setter
+        w.Local valueLocal = paramLocals[1];
+        getThis();
+        b.local_get(valueLocal);
+        translator.convertType(function, valueLocal.type, fieldType);
+        b.struct_set(struct, fieldIndex);
+      }
+      b.end();
+      return;
+    }
+
+    ParameterInfo paramInfo = translator.paramInfoFor(reference);
+    bool hasThis = member.isInstanceMember || member is Constructor;
+    int typeParameterOffset = hasThis ? 1 : 0;
+    int implicitParams = typeParameterOffset + paramInfo.typeParamCount;
+    List<VariableDeclaration> positional =
+        member.function!.positionalParameters;
+    for (int i = 0; i < positional.length; i++) {
+      locals[positional[i]] = paramLocals[implicitParams + i];
+    }
+    List<VariableDeclaration> named = member.function!.namedParameters;
+    for (var param in named) {
+      locals[param] =
+          paramLocals[implicitParams + paramInfo.nameIndex[param.name]!];
+    }
+    List<TypeParameter> typeParameters = member is Constructor
+        ? member.enclosingClass.typeParameters
+        : member.function!.typeParameters;
+    for (int i = 0; i < typeParameters.length; i++) {
+      typeLocals[typeParameters[i]] = paramLocals[typeParameterOffset + i];
+    }
+
+    closures.findCaptures(member);
+
+    if (hasThis) {
+      Class cls = member.enclosingClass!;
+      ClassInfo info = translator.classInfo[cls]!;
+      thisLocal = paramLocals[0];
+      w.RefType thisType = info.nonNullableType;
+      if (translator.needsConversion(paramLocals[0].type, thisType)) {
+        preciseThisLocal = addLocal(thisType);
+        b.local_get(paramLocals[0]);
+        translator.ref_cast(b, info);
+        b.local_set(preciseThisLocal!);
+      } else {
+        preciseThisLocal = paramLocals[0];
+      }
+    }
+
+    closures.collectContexts(member);
+    if (member is Constructor) {
+      for (Field field in member.enclosingClass.fields) {
+        if (field.isInstanceMember && field.initializer != null) {
+          closures.collectContexts(field.initializer!,
+              container: member.function);
+        }
+      }
+    }
+    closures.buildContexts();
+
+    allocateContext(member.function!);
+    captureParameters();
+
+    if (member is Constructor) {
+      Class cls = member.enclosingClass;
+      ClassInfo info = translator.classInfo[cls]!;
+      for (TypeParameter typeParam in cls.typeParameters) {
+        b.local_get(thisLocal!);
+        b.local_get(typeLocals[typeParam]!);
+        b.struct_set(info.struct, translator.typeParameterIndex[typeParam]!);
+      }
+      for (Field field in cls.fields) {
+        if (field.isInstanceMember && field.initializer != null) {
+          int fieldIndex = translator.fieldIndex[field]!;
+          b.local_get(thisLocal!);
+          wrap(
+              field.initializer!, info.struct.fields[fieldIndex].type.unpacked);
+          b.struct_set(info.struct, fieldIndex);
+        }
+      }
+      for (Initializer initializer in member.initializers) {
+        initializer.accept(this);
+      }
+    }
+
+    member.function!.body?.accept(this);
+    _implicitReturn();
+    b.end();
+  }
+
+  /// Generate code for the body of a lambda.
+  void generateLambda(Lambda lambda, Closures closures) {
+    this.closures = closures;
+
+    final int implicitParams = 1;
+    List<VariableDeclaration> positional =
+        lambda.functionNode.positionalParameters;
+    for (int i = 0; i < positional.length; i++) {
+      locals[positional[i]] = paramLocals[implicitParams + i];
+    }
+
+    Context? context = closures.contexts[lambda.functionNode]?.parent;
+    if (context != null) {
+      b.local_get(paramLocals[0]);
+      translator.ref_cast(b, context.struct);
+      while (true) {
+        w.Local contextLocal =
+            addLocal(w.RefType.def(context!.struct, nullable: false));
+        context.currentLocal = contextLocal;
+        if (context.parent != null || context.containsThis) {
+          b.local_tee(contextLocal);
+        } else {
+          b.local_set(contextLocal);
+        }
+        if (context.parent == null) break;
+
+        b.struct_get(context.struct, context.parentFieldIndex);
+        if (options.localNullability) {
+          b.ref_as_non_null();
+        }
+        context = context.parent!;
+      }
+      if (context.containsThis) {
+        thisLocal = addLocal(
+            context.struct.fields[context.thisFieldIndex].type.unpacked);
+        preciseThisLocal = thisLocal;
+        b.struct_get(context.struct, context.thisFieldIndex);
+        b.local_set(thisLocal!);
+      }
+    }
+    allocateContext(lambda.functionNode);
+    captureParameters();
+
+    lambda.functionNode.body!.accept(this);
+    _implicitReturn();
+    b.end();
+  }
+
+  void _implicitReturn() {
+    if (function.type.outputs.length > 0) {
+      w.ValueType returnType = function.type.outputs[0];
+      if (returnType is w.RefType && returnType.nullable) {
+        // Dart body may have an implicit return null.
+        b.ref_null(returnType.heapType);
+      } else {
+        // This point is unreachable, but the Wasm validator still expects the
+        // stack to contain a value matching the Wasm function return type.
+        b.block(const [], function.type.outputs);
+        b.comment("Unreachable implicit return");
+        b.unreachable();
+        b.end();
+      }
+    }
+  }
+
+  void allocateContext(TreeNode node) {
+    Context? context = closures.contexts[node];
+    if (context != null && !context.isEmpty) {
+      w.Local contextLocal =
+          addLocal(w.RefType.def(context.struct, nullable: false));
+      context.currentLocal = contextLocal;
+      translator.struct_new_default(b, context.struct);
+      b.local_set(contextLocal);
+      if (context.containsThis) {
+        b.local_get(contextLocal);
+        b.local_get(preciseThisLocal!);
+        b.struct_set(context.struct, context.thisFieldIndex);
+      }
+      if (context.parent != null) {
+        w.Local parentLocal = context.parent!.currentLocal;
+        b.local_get(contextLocal);
+        b.local_get(parentLocal);
+        b.struct_set(context.struct, context.parentFieldIndex);
+      }
+    }
+  }
+
+  void captureParameters() {
+    locals.forEach((variable, local) {
+      Capture? capture = closures.captures[variable];
+      if (capture != null) {
+        b.local_get(capture.context.currentLocal);
+        b.local_get(local);
+        translator.convertType(function, local.type, capture.type);
+        b.struct_set(capture.context.struct, capture.fieldIndex);
+      }
+    });
+  }
+
+  /// Generates code for an expression plus conversion code to convert the
+  /// result to the expected type if needed. All expression code generation goes
+  /// through this method.
+  w.ValueType wrap(Expression node, w.ValueType expectedType) {
+    w.ValueType resultType = node.accept1(this, expectedType);
+    translator.convertType(function, resultType, expectedType);
+    return expectedType;
+  }
+
+  w.ValueType _call(Reference target) {
+    w.BaseFunction targetFunction = translator.functions.getFunction(target);
+    if (translator.shouldInline(target)) {
+      List<w.Local> inlinedLocals =
+          targetFunction.type.inputs.map((t) => addLocal(t)).toList();
+      for (w.Local local in inlinedLocals.reversed) {
+        b.local_set(local);
+      }
+      w.Label block = b.block(const [], targetFunction.type.outputs);
+      b.comment("Inlined ${target.asMember}");
+      CodeGenerator(translator, function, target,
+              paramLocals: inlinedLocals, returnLabel: block)
+          .generate();
+    } else {
+      String access =
+          target.isGetter ? "get" : (target.isSetter ? "set" : "call");
+      b.comment("Direct $access of '${target.asMember}'");
+      b.call(targetFunction);
+    }
+    return translator.outputOrVoid(targetFunction.type.outputs);
+  }
+
+  @override
+  void visitInvalidInitializer(InvalidInitializer node) {}
+
+  @override
+  void visitAssertInitializer(AssertInitializer node) {}
+
+  @override
+  void visitLocalInitializer(LocalInitializer node) {
+    node.variable.accept(this);
+  }
+
+  @override
+  void visitFieldInitializer(FieldInitializer node) {
+    Class cls = (node.parent as Constructor).enclosingClass;
+    w.StructType struct = translator.classInfo[cls]!.struct;
+    int fieldIndex = translator.fieldIndex[node.field]!;
+
+    b.local_get(thisLocal!);
+    wrap(node.value, struct.fields[fieldIndex].type.unpacked);
+    b.struct_set(struct, fieldIndex);
+  }
+
+  @override
+  void visitRedirectingInitializer(RedirectingInitializer node) {
+    Class cls = (node.parent as Constructor).enclosingClass;
+    b.local_get(thisLocal!);
+    if (options.parameterNullability && thisLocal!.type.nullable) {
+      b.ref_as_non_null();
+    }
+    for (TypeParameter typeParam in cls.typeParameters) {
+      _makeType(TypeParameterType(typeParam, Nullability.nonNullable), node);
+    }
+    _visitArguments(node.arguments, node.targetReference, 1);
+    _call(node.targetReference);
+  }
+
+  @override
+  void visitSuperInitializer(SuperInitializer node) {
+    Supertype? supertype =
+        (node.parent as Constructor).enclosingClass.supertype;
+    if (supertype?.classNode.superclass == null) {
+      return;
+    }
+    b.local_get(thisLocal!);
+    if (options.parameterNullability && thisLocal!.type.nullable) {
+      b.ref_as_non_null();
+    }
+    for (DartType typeArg in supertype!.typeArguments) {
+      _makeType(typeArg, node);
+    }
+    _visitArguments(node.arguments, node.targetReference,
+        1 + supertype.typeArguments.length);
+    _call(node.targetReference);
+  }
+
+  @override
+  void visitBlock(Block node) {
+    for (Statement statement in node.statements) {
+      statement.accept(this);
+    }
+  }
+
+  @override
+  void visitLabeledStatement(LabeledStatement node) {
+    w.Label label = b.block();
+    labels[node] = label;
+    node.body.accept(this);
+    labels.remove(node);
+    b.end();
+  }
+
+  @override
+  void visitBreakStatement(BreakStatement node) {
+    b.br(labels[node.target]!);
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    if (node.type is VoidType) {
+      if (node.initializer != null) {
+        wrap(node.initializer!, voidMarker);
+      }
+      return;
+    }
+    w.ValueType type = translateType(node.type);
+    w.Local? local;
+    Capture? capture = closures.captures[node];
+    if (capture == null || !capture.written) {
+      local = addLocal(type);
+      locals[node] = local;
+    }
+    if (node.initializer != null) {
+      if (capture != null) {
+        w.ValueType expectedType = capture.written ? capture.type : local!.type;
+        b.local_get(capture.context.currentLocal);
+        wrap(node.initializer!, expectedType);
+        if (!capture.written) {
+          b.local_tee(local!);
+        }
+        b.struct_set(capture.context.struct, capture.fieldIndex);
+      } else {
+        wrap(node.initializer!, local!.type);
+        b.local_set(local);
+      }
+    } else if (local != null && !local.type.defaultable) {
+      // Uninitialized variable
+      translator.globals.instantiateDummyValue(b, local.type);
+      b.local_set(local);
+    }
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {}
+
+  @override
+  void visitAssertStatement(AssertStatement node) {}
+
+  @override
+  void visitAssertBlock(AssertBlock node) {}
+
+  @override
+  void visitTryCatch(TryCatch node) {
+    // TODO(joshualitt): Include catches
+    node.body.accept(this);
+  }
+
+  @override
+  void visitTryFinally(TryFinally node) {
+    finalizers.add(node.finalizer);
+    node.body.accept(this);
+    finalizers.removeLast().accept(this);
+  }
+
+  @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    wrap(node.expression, voidMarker);
+  }
+
+  bool _hasLogicalOperator(Expression condition) {
+    while (condition is Not) condition = condition.operand;
+    return condition is LogicalExpression;
+  }
+
+  void _branchIf(Expression? condition, w.Label target,
+      {required bool negated}) {
+    if (condition == null) {
+      if (!negated) b.br(target);
+      return;
+    }
+    while (condition is Not) {
+      negated = !negated;
+      condition = condition.operand;
+    }
+    if (condition is LogicalExpression) {
+      bool isConjunctive =
+          (condition.operatorEnum == LogicalExpressionOperator.AND) ^ negated;
+      if (isConjunctive) {
+        w.Label conditionBlock = b.block();
+        _branchIf(condition.left, conditionBlock, negated: !negated);
+        _branchIf(condition.right, target, negated: negated);
+        b.end();
+      } else {
+        _branchIf(condition.left, target, negated: negated);
+        _branchIf(condition.right, target, negated: negated);
+      }
+    } else {
+      wrap(condition!, w.NumType.i32);
+      if (negated) {
+        b.i32_eqz();
+      }
+      b.br_if(target);
+    }
+  }
+
+  void _conditional(Expression condition, void then(), void otherwise()?,
+      List<w.ValueType> result) {
+    if (!_hasLogicalOperator(condition)) {
+      // Simple condition
+      wrap(condition, w.NumType.i32);
+      b.if_(const [], result);
+      then();
+      if (otherwise != null) {
+        b.else_();
+        otherwise();
+      }
+      b.end();
+    } else {
+      // Complex condition
+      w.Label ifBlock = b.block(const [], result);
+      if (otherwise != null) {
+        w.Label elseBlock = b.block();
+        _branchIf(condition, elseBlock, negated: true);
+        then();
+        b.br(ifBlock);
+        b.end();
+        otherwise();
+      } else {
+        _branchIf(condition, ifBlock, negated: true);
+        then();
+      }
+      b.end();
+    }
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    _conditional(
+        node.condition,
+        () => node.then.accept(this),
+        node.otherwise != null ? () => node.otherwise!.accept(this) : null,
+        const []);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    w.Label loop = b.loop();
+    allocateContext(node);
+    node.body.accept(this);
+    _branchIf(node.condition, loop, negated: false);
+    b.end();
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    w.Label block = b.block();
+    w.Label loop = b.loop();
+    _branchIf(node.condition, block, negated: true);
+    allocateContext(node);
+    node.body.accept(this);
+    b.br(loop);
+    b.end();
+    b.end();
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    Context? context = closures.contexts[node];
+    allocateContext(node);
+    for (VariableDeclaration variable in node.variables) {
+      variable.accept(this);
+    }
+    w.Label block = b.block();
+    w.Label loop = b.loop();
+    _branchIf(node.condition, block, negated: true);
+    node.body.accept(this);
+    if (node.variables.any((v) => closures.captures.containsKey(v))) {
+      w.Local oldContext = context!.currentLocal;
+      allocateContext(node);
+      w.Local newContext = context.currentLocal;
+      for (VariableDeclaration variable in node.variables) {
+        Capture? capture = closures.captures[variable];
+        if (capture != null) {
+          b.local_get(oldContext);
+          b.struct_get(context.struct, capture.fieldIndex);
+          b.local_get(newContext);
+          b.struct_set(context.struct, capture.fieldIndex);
+        }
+      }
+    } else {
+      allocateContext(node);
+    }
+    for (Expression update in node.updates) {
+      wrap(update, voidMarker);
+    }
+    b.br(loop);
+    b.end();
+    b.end();
+  }
+
+  @override
+  void visitForInStatement(ForInStatement node) {
+    throw "ForInStatement should have been desugared: $node";
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    Expression? expression = node.expression;
+    if (expression != null) {
+      wrap(expression, returnType);
+    } else {
+      translator.convertType(function, voidMarker, returnType);
+    }
+    for (Statement finalizer in finalizers.reversed) {
+      finalizer.accept(this);
+    }
+    if (returnLabel != null) {
+      b.br(returnLabel!);
+    } else {
+      b.return_();
+    }
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    bool check<L extends Expression, C extends Constant>() =>
+        node.cases.expand((c) => c.expressions).every((e) =>
+            e is L ||
+            e is NullLiteral ||
+            e is ConstantExpression &&
+                (e.constant is C || e.constant is NullConstant));
+
+    // Identify kind of switch
+    w.ValueType valueType;
+    w.ValueType nullableType;
+    void Function() compare;
+    if (check<BoolLiteral, BoolConstant>()) {
+      // bool switch
+      valueType = w.NumType.i32;
+      nullableType =
+          translator.classInfo[translator.boxedBoolClass]!.nullableType;
+      compare = () => b.i32_eq();
+    } else if (check<IntLiteral, IntConstant>()) {
+      // int switch
+      valueType = w.NumType.i64;
+      nullableType =
+          translator.classInfo[translator.boxedIntClass]!.nullableType;
+      compare = () => b.i64_eq();
+    } else if (check<StringLiteral, StringConstant>()) {
+      // String switch
+      valueType =
+          translator.classInfo[translator.stringBaseClass]!.nonNullableType;
+      nullableType = valueType.withNullability(true);
+      compare = () => _call(translator.stringEquals.reference);
+    } else {
+      // Object switch
+      assert(check<InvalidExpression, InstanceConstant>());
+      valueType = w.RefType.eq(nullable: false);
+      nullableType = w.RefType.eq(nullable: true);
+      compare = () => b.ref_eq();
+    }
+    w.Local valueLocal = addLocal(valueType);
+
+    // Special cases
+    SwitchCase? defaultCase = node.cases
+        .cast<SwitchCase?>()
+        .firstWhere((c) => c!.isDefault, orElse: () => null);
+    SwitchCase? nullCase = node.cases.cast<SwitchCase?>().firstWhere(
+        (c) => c!.expressions.any((e) =>
+            e is NullLiteral ||
+            e is ConstantExpression && e.constant is NullConstant),
+        orElse: () => null);
+
+    // Set up blocks, in reverse order of cases so they end in forward order
+    w.Label doneLabel = b.block();
+    for (SwitchCase c in node.cases.reversed) {
+      switchLabels[c] = b.block();
+    }
+
+    // Compute value and handle null
+    bool isNullable = dartTypeOf(node.expression).isPotentiallyNullable;
+    if (isNullable) {
+      w.Label nullLabel = nullCase != null
+          ? switchLabels[nullCase]!
+          : defaultCase != null
+              ? switchLabels[defaultCase]!
+              : doneLabel;
+      wrap(node.expression, nullableType);
+      b.br_on_null(nullLabel);
+      translator.convertType(
+          function, nullableType.withNullability(false), valueType);
+    } else {
+      assert(nullCase == null);
+      wrap(node.expression, valueType);
+    }
+    b.local_set(valueLocal);
+
+    // Compare against all case values
+    for (SwitchCase c in node.cases) {
+      for (Expression exp in c.expressions) {
+        if (exp is NullLiteral ||
+            exp is ConstantExpression && exp.constant is NullConstant) {
+          // Null already checked, skip
+        } else {
+          wrap(exp, valueType);
+          b.local_get(valueLocal);
+          translator.convertType(function, valueLocal.type, valueType);
+          compare();
+          b.br_if(switchLabels[c]!);
+        }
+      }
+    }
+    w.Label defaultLabel =
+        defaultCase != null ? switchLabels[defaultCase]! : doneLabel;
+    b.br(defaultLabel);
+
+    // Emit case bodies
+    for (SwitchCase c in node.cases) {
+      switchLabels.remove(c);
+      b.end();
+      c.body.accept(this);
+      b.br(doneLabel);
+    }
+    b.end();
+  }
+
+  @override
+  void visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    w.Label? label = switchLabels[node.target];
+    if (label != null) {
+      b.br(label);
+    } else {
+      throw "Not supported: Backward jump to switch case at ${node.location}";
+    }
+  }
+
+  @override
+  void visitYieldStatement(YieldStatement node) => defaultStatement(node);
+
+  @override
+  w.ValueType visitBlockExpression(
+      BlockExpression node, w.ValueType expectedType) {
+    node.body.accept(this);
+    return wrap(node.value, expectedType);
+  }
+
+  @override
+  w.ValueType visitLet(Let node, w.ValueType expectedType) {
+    node.variable.accept(this);
+    return wrap(node.body, expectedType);
+  }
+
+  @override
+  w.ValueType visitThisExpression(
+      ThisExpression node, w.ValueType expectedType) {
+    return _visitThis(expectedType);
+  }
+
+  w.ValueType _visitThis(w.ValueType expectedType) {
+    w.ValueType thisType = thisLocal!.type.withNullability(false);
+    w.ValueType preciseThisType = preciseThisLocal!.type.withNullability(false);
+    if (!thisType.isSubtypeOf(expectedType) &&
+        preciseThisType.isSubtypeOf(expectedType)) {
+      b.local_get(preciseThisLocal!);
+      return preciseThisLocal!.type;
+    } else {
+      b.local_get(thisLocal!);
+      return thisLocal!.type;
+    }
+  }
+
+  @override
+  w.ValueType visitConstructorInvocation(
+      ConstructorInvocation node, w.ValueType expectedType) {
+    ClassInfo info = translator.classInfo[node.target.enclosingClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.Local temp = addLocal(info.nonNullableType);
+    translator.struct_new_default(b, info);
+    b.local_tee(temp);
+    b.local_get(temp);
+    b.i32_const(info.classId);
+    b.struct_set(info.struct, FieldIndex.classId);
+    if (options.parameterNullability && temp.type.nullable) {
+      b.ref_as_non_null();
+    }
+    _visitArguments(node.arguments, node.targetReference, 1);
+    _call(node.targetReference);
+    if (expectedType != voidMarker) {
+      b.local_get(temp);
+      return temp.type;
+    } else {
+      return voidMarker;
+    }
+  }
+
+  @override
+  w.ValueType visitStaticInvocation(
+      StaticInvocation node, w.ValueType expectedType) {
+    w.ValueType? intrinsicResult = intrinsifier.generateStaticIntrinsic(node);
+    if (intrinsicResult != null) return intrinsicResult;
+    _visitArguments(node.arguments, node.targetReference, 0);
+    return _call(node.targetReference);
+  }
+
+  Member _lookupSuperTarget(Member interfaceTarget, {required bool setter}) {
+    return translator.hierarchy.getDispatchTarget(
+        member.enclosingClass!.superclass!, interfaceTarget.name,
+        setter: setter)!;
+  }
+
+  @override
+  w.ValueType visitSuperMethodInvocation(
+      SuperMethodInvocation node, w.ValueType expectedType) {
+    Reference target =
+        _lookupSuperTarget(node.interfaceTarget!, setter: false).reference;
+    w.BaseFunction targetFunction = translator.functions.getFunction(target);
+    w.ValueType receiverType = targetFunction.type.inputs.first;
+    w.ValueType thisType = _visitThis(receiverType);
+    translator.convertType(function, thisType, receiverType);
+    _visitArguments(node.arguments, target, 1);
+    return _call(target);
+  }
+
+  @override
+  w.ValueType visitInstanceInvocation(
+      InstanceInvocation node, w.ValueType expectedType) {
+    w.ValueType? intrinsicResult = intrinsifier.generateInstanceIntrinsic(node);
+    if (intrinsicResult != null) return intrinsicResult;
+    Procedure target = node.interfaceTarget;
+    if (node.kind == InstanceAccessKind.Object) {
+      switch (target.name.text) {
+        case "toString":
+          late w.Label done;
+          w.ValueType resultType = _virtualCall(node, target, (signature) {
+            done = b.block(const [], signature.outputs);
+            w.Label nullString = b.block();
+            wrap(node.receiver, translator.topInfo.nullableType);
+            b.br_on_null(nullString);
+          }, (_) {
+            _visitArguments(node.arguments, node.interfaceTargetReference, 1);
+          }, getter: false, setter: false);
+          b.br(done);
+          b.end();
+          wrap(StringLiteral("null"), resultType);
+          b.end();
+          return resultType;
+        default:
+          _unimplemented(node, "Nullable invocation of ${target.name.text}",
+              [if (expectedType != voidMarker) expectedType]);
+          return expectedType;
+      }
+    }
+    Member? singleTarget = translator.singleTarget(node);
+    if (singleTarget != null) {
+      w.BaseFunction targetFunction =
+          translator.functions.getFunction(singleTarget.reference);
+      wrap(node.receiver, targetFunction.type.inputs.first);
+      _visitArguments(node.arguments, node.interfaceTargetReference, 1);
+      return _call(singleTarget.reference);
+    }
+    return _virtualCall(node, target,
+        (signature) => wrap(node.receiver, signature.inputs.first), (_) {
+      _visitArguments(node.arguments, node.interfaceTargetReference, 1);
+    }, getter: false, setter: false);
+  }
+
+  @override
+  w.ValueType visitDynamicInvocation(
+      DynamicInvocation node, w.ValueType expectedType) {
+    if (node.name.text != "call") {
+      _unimplemented(node, "Dynamic invocation of ${node.name.text}",
+          [if (expectedType != voidMarker) expectedType]);
+      return expectedType;
+    }
+    return _functionCall(
+        node.arguments.positional.length, node.receiver, node.arguments);
+  }
+
+  @override
+  w.ValueType visitEqualsCall(EqualsCall node, w.ValueType expectedType) {
+    w.ValueType? intrinsicResult = intrinsifier.generateEqualsIntrinsic(node);
+    if (intrinsicResult != null) return intrinsicResult;
+    Member? singleTarget = translator.singleTarget(node);
+    if (singleTarget == translator.coreTypes.objectEquals) {
+      // Plain reference comparison
+      wrap(node.left, w.RefType.eq(nullable: true));
+      wrap(node.right, w.RefType.eq(nullable: true));
+      b.ref_eq();
+    } else {
+      // Check operands for null, then call implementation
+      bool leftNullable = dartTypeOf(node.left).isPotentiallyNullable;
+      bool rightNullable = dartTypeOf(node.right).isPotentiallyNullable;
+      w.RefType leftType = translator.topInfo.typeWithNullability(leftNullable);
+      w.RefType rightType =
+          translator.topInfo.typeWithNullability(rightNullable);
+      w.Local leftLocal = addLocal(leftType);
+      w.Local rightLocal = addLocal(rightType);
+      w.Label? operandNull;
+      w.Label? done;
+      if (leftNullable || rightNullable) {
+        done = b.block(const [], const [w.NumType.i32]);
+        operandNull = b.block();
+      }
+      wrap(node.left, leftLocal.type);
+      b.local_set(leftLocal);
+      wrap(node.right, rightLocal.type);
+      if (rightNullable) {
+        b.local_tee(rightLocal);
+        b.br_on_null(operandNull!);
+        b.drop();
+      } else {
+        b.local_set(rightLocal);
+      }
+
+      void left([_]) {
+        b.local_get(leftLocal);
+        if (leftNullable) {
+          b.br_on_null(operandNull!);
+        } else if (leftLocal.type.nullable) {
+          b.ref_as_non_null();
+        }
+      }
+
+      void right([_]) {
+        b.local_get(rightLocal);
+        if (rightLocal.type.nullable) {
+          b.ref_as_non_null();
+        }
+      }
+
+      if (singleTarget != null) {
+        left();
+        right();
+        _call(singleTarget.reference);
+      } else {
+        _virtualCall(node, node.interfaceTarget, left, right,
+            getter: false, setter: false);
+      }
+      if (leftNullable || rightNullable) {
+        b.br(done!);
+        b.end(); // operandNull
+        if (leftNullable && rightNullable) {
+          // Both sides nullable - compare references
+          b.local_get(leftLocal);
+          b.local_get(rightLocal);
+          b.ref_eq();
+        } else {
+          // Only one side nullable - not equal if one is null
+          b.i32_const(0);
+        }
+        b.end(); // done
+      }
+    }
+    return w.NumType.i32;
+  }
+
+  @override
+  w.ValueType visitEqualsNull(EqualsNull node, w.ValueType expectedType) {
+    wrap(node.expression, translator.topInfo.nullableType);
+    b.ref_is_null();
+    return w.NumType.i32;
+  }
+
+  w.ValueType _virtualCall(
+      TreeNode node,
+      Member interfaceTarget,
+      void pushReceiver(w.FunctionType signature),
+      void pushArguments(w.FunctionType signature),
+      {required bool getter,
+      required bool setter}) {
+    SelectorInfo selector = translator.dispatchTable.selectorForTarget(
+        interfaceTarget.referenceAs(getter: getter, setter: setter));
+    assert(selector.name == interfaceTarget.name.text);
+
+    pushReceiver(selector.signature);
+
+    int? offset = selector.offset;
+    if (offset == null) {
+      // Singular target or unreachable call
+      assert(selector.targetCount <= 1);
+      if (selector.targetCount == 1) {
+        pushArguments(selector.signature);
+        return _call(selector.singularTarget!);
+      } else {
+        b.comment("Virtual call of ${selector.name} with no targets"
+            " at ${node.location}");
+        b.drop();
+        b.block(const [], selector.signature.outputs);
+        b.unreachable();
+        b.end();
+        return translator.outputOrVoid(selector.signature.outputs);
+      }
+    }
+
+    // Receiver is already on stack.
+    w.Local receiverVar = addLocal(selector.signature.inputs.first);
+    b.local_tee(receiverVar);
+    if (options.parameterNullability && receiverVar.type.nullable) {
+      b.ref_as_non_null();
+    }
+    pushArguments(selector.signature);
+
+    if (options.polymorphicSpecialization) {
+      _polymorphicSpecialization(selector, receiverVar);
+    } else {
+      String access = getter ? "get" : (setter ? "set" : "call");
+      b.comment("Instance $access of '${selector.name}'");
+      b.local_get(receiverVar);
+      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+      if (offset != 0) {
+        b.i32_const(offset);
+        b.i32_add();
+      }
+      b.call_indirect(selector.signature);
+
+      translator.functions.activateSelector(selector);
+    }
+
+    return translator.outputOrVoid(selector.signature.outputs);
+  }
+
+  void _polymorphicSpecialization(SelectorInfo selector, w.Local receiver) {
+    Map<int, Reference> implementations = Map.from(selector.targets);
+    implementations.removeWhere((id, target) => target.asMember.isAbstract);
+
+    w.Local idVar = addLocal(w.NumType.i32);
+    b.local_get(receiver);
+    b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+    b.local_set(idVar);
+
+    w.Label block =
+        b.block(selector.signature.inputs, selector.signature.outputs);
+    calls:
+    while (Set.from(implementations.values).length > 1) {
+      for (int id in implementations.keys) {
+        Reference target = implementations[id]!;
+        if (implementations.values.where((t) => t == target).length == 1) {
+          // Single class id implements method.
+          b.local_get(idVar);
+          b.i32_const(id);
+          b.i32_eq();
+          b.if_(selector.signature.inputs, selector.signature.inputs);
+          _call(target);
+          b.br(block);
+          b.end();
+          implementations.remove(id);
+          continue calls;
+        }
+      }
+      // Find class id that separates remaining classes in two.
+      List<int> sorted = implementations.keys.toList()..sort();
+      int pivotId = sorted.firstWhere(
+          (id) => implementations[id] != implementations[sorted.first]);
+      // Fail compilation if no such id exists.
+      assert(sorted.lastWhere(
+              (id) => implementations[id] != implementations[pivotId]) ==
+          pivotId - 1);
+      Reference target = implementations[sorted.first]!;
+      b.local_get(idVar);
+      b.i32_const(pivotId);
+      b.i32_lt_u();
+      b.if_(selector.signature.inputs, selector.signature.inputs);
+      _call(target);
+      b.br(block);
+      b.end();
+      for (int id in sorted) {
+        if (id == pivotId) break;
+        implementations.remove(id);
+      }
+      continue calls;
+    }
+    // Call remaining implementation.
+    Reference target = implementations.values.first;
+    _call(target);
+    b.end();
+  }
+
+  @override
+  w.ValueType visitVariableGet(VariableGet node, w.ValueType expectedType) {
+    w.Local? local = locals[node.variable];
+    Capture? capture = closures.captures[node.variable];
+    if (capture != null) {
+      if (!capture.written && local != null) {
+        b.local_get(local);
+        return local.type;
+      } else {
+        b.local_get(capture.context.currentLocal);
+        b.struct_get(capture.context.struct, capture.fieldIndex);
+        return capture.type;
+      }
+    } else {
+      if (local == null) {
+        throw "Read of undefined variable ${node.variable}";
+      }
+      b.local_get(local);
+      return local.type;
+    }
+  }
+
+  @override
+  w.ValueType visitVariableSet(VariableSet node, w.ValueType expectedType) {
+    w.Local? local = locals[node.variable];
+    Capture? capture = closures.captures[node.variable];
+    bool preserved = expectedType != voidMarker;
+    if (capture != null) {
+      assert(capture.written);
+      b.local_get(capture.context.currentLocal);
+      wrap(node.value, capture.type);
+      if (preserved) {
+        w.Local temp = addLocal(translateType(node.variable.type));
+        b.local_tee(temp);
+        b.struct_set(capture.context.struct, capture.fieldIndex);
+        b.local_get(temp);
+        return temp.type;
+      } else {
+        b.struct_set(capture.context.struct, capture.fieldIndex);
+        return voidMarker;
+      }
+    } else {
+      if (local == null) {
+        throw "Write of undefined variable ${node.variable}";
+      }
+      wrap(node.value, local.type);
+      if (preserved) {
+        b.local_tee(local);
+        return local.type;
+      } else {
+        b.local_set(local);
+        return voidMarker;
+      }
+    }
+  }
+
+  @override
+  w.ValueType visitStaticGet(StaticGet node, w.ValueType expectedType) {
+    w.ValueType? intrinsicResult =
+        intrinsifier.generateStaticGetterIntrinsic(node);
+    if (intrinsicResult != null) return intrinsicResult;
+    Member target = node.target;
+    if (target is Field) {
+      return translator.globals.readGlobal(b, target);
+    } else {
+      return _call(target.reference);
+    }
+  }
+
+  @override
+  w.ValueType visitStaticTearOff(StaticTearOff node, w.ValueType expectedType) {
+    translator.constants.instantiateConstant(
+        function, b, StaticTearOffConstant(node.target), expectedType);
+    return expectedType;
+  }
+
+  @override
+  w.ValueType visitStaticSet(StaticSet node, w.ValueType expectedType) {
+    bool preserved = expectedType != voidMarker;
+    Member target = node.target;
+    if (target is Field) {
+      w.Global global = translator.globals.getGlobal(target);
+      wrap(node.value, global.type.type);
+      b.global_set(global);
+      if (preserved) {
+        b.global_get(global);
+        return global.type.type;
+      } else {
+        return voidMarker;
+      }
+    } else {
+      w.BaseFunction targetFunction =
+          translator.functions.getFunction(target.reference);
+      wrap(node.value, targetFunction.type.inputs.single);
+      w.Local? temp;
+      if (preserved) {
+        temp = addLocal(translateType(dartTypeOf(node.value)));
+        b.local_tee(temp);
+      }
+      _call(target.reference);
+      if (preserved) {
+        b.local_get(temp!);
+        return temp.type;
+      } else {
+        return voidMarker;
+      }
+    }
+  }
+
+  @override
+  w.ValueType visitSuperPropertyGet(
+      SuperPropertyGet node, w.ValueType expectedType) {
+    Member target = _lookupSuperTarget(node.interfaceTarget!, setter: false);
+    if (target is Procedure && !target.isGetter) {
+      throw "Not supported: Super tear-off at ${node.location}";
+    }
+    return _directGet(target, ThisExpression(), () => null);
+  }
+
+  @override
+  w.ValueType visitSuperPropertySet(
+      SuperPropertySet node, w.ValueType expectedType) {
+    Member target = _lookupSuperTarget(node.interfaceTarget!, setter: true);
+    return _directSet(target, ThisExpression(), node.value,
+        preserved: expectedType != voidMarker);
+  }
+
+  @override
+  w.ValueType visitInstanceGet(InstanceGet node, w.ValueType expectedType) {
+    Member target = node.interfaceTarget;
+    if (node.kind == InstanceAccessKind.Object) {
+      late w.Label doneLabel;
+      w.ValueType resultType = _virtualCall(node, target, (signature) {
+        doneLabel = b.block(const [], signature.outputs);
+        w.Label nullLabel = b.block();
+        wrap(node.receiver, translator.topInfo.nullableType);
+        b.br_on_null(nullLabel);
+      }, (_) {}, getter: true, setter: false);
+      b.br(doneLabel);
+      b.end(); // nullLabel
+      switch (target.name.text) {
+        case "hashCode":
+          b.i64_const(2011);
+          break;
+        case "runtimeType":
+          wrap(ConstantExpression(TypeLiteralConstant(NullType())), resultType);
+          break;
+        default:
+          _unimplemented(
+              node, "Nullable get of ${target.name.text}", [resultType]);
+          break;
+      }
+      b.end(); // doneLabel
+      return resultType;
+    }
+    Member? singleTarget = translator.singleTarget(node);
+    if (singleTarget != null) {
+      return _directGet(singleTarget, node.receiver,
+          () => intrinsifier.generateInstanceGetterIntrinsic(node));
+    } else {
+      return _virtualCall(node, target,
+          (signature) => wrap(node.receiver, signature.inputs.first), (_) {},
+          getter: true, setter: false);
+    }
+  }
+
+  @override
+  w.ValueType visitDynamicGet(DynamicGet node, w.ValueType expectedType) {
+    // Provisional implementation of dynamic get which assumes the getter
+    // is present (otherwise it traps or calls something random) and
+    // does not support tearoffs. This is sufficient to handle the
+    // dynamic .length calls in the core libraries.
+
+    SelectorInfo selector =
+        translator.dispatchTable.selectorForDynamicName(node.name.text);
+
+    // Evaluate receiver
+    wrap(node.receiver, selector.signature.inputs.first);
+    w.Local receiverVar = addLocal(selector.signature.inputs.first);
+    b.local_tee(receiverVar);
+    if (options.parameterNullability && receiverVar.type.nullable) {
+      b.ref_as_non_null();
+    }
+
+    // Dispatch table call
+    b.comment("Dynamic get of '${selector.name}'");
+    int offset = selector.offset!;
+    b.local_get(receiverVar);
+    b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+    if (offset != 0) {
+      b.i32_const(offset);
+      b.i32_add();
+    }
+    b.call_indirect(selector.signature);
+
+    translator.functions.activateSelector(selector);
+
+    return translator.outputOrVoid(selector.signature.outputs);
+  }
+
+  w.ValueType _directGet(
+      Member target, Expression receiver, w.ValueType? Function() intrinsify) {
+    if (target is Field) {
+      ClassInfo info = translator.classInfo[target.enclosingClass]!;
+      int fieldIndex = translator.fieldIndex[target]!;
+      w.ValueType receiverType = info.nullableType;
+      w.ValueType fieldType = info.struct.fields[fieldIndex].type.unpacked;
+      wrap(receiver, receiverType);
+      b.struct_get(info.struct, fieldIndex);
+      return fieldType;
+    } else {
+      // Instance call of getter
+      assert(target is Procedure && target.isGetter);
+      w.ValueType? intrinsicResult = intrinsify();
+      if (intrinsicResult != null) return intrinsicResult;
+      w.BaseFunction targetFunction =
+          translator.functions.getFunction(target.reference);
+      wrap(receiver, targetFunction.type.inputs.single);
+      return _call(target.reference);
+    }
+  }
+
+  @override
+  w.ValueType visitInstanceTearOff(
+      InstanceTearOff node, w.ValueType expectedType) {
+    return _virtualCall(node, node.interfaceTarget,
+        (signature) => wrap(node.receiver, signature.inputs.first), (_) {},
+        getter: true, setter: false);
+  }
+
+  @override
+  w.ValueType visitInstanceSet(InstanceSet node, w.ValueType expectedType) {
+    bool preserved = expectedType != voidMarker;
+    w.Local? temp;
+    Member? singleTarget = translator.singleTarget(node);
+    if (singleTarget != null) {
+      return _directSet(singleTarget, node.receiver, node.value,
+          preserved: preserved);
+    } else {
+      _virtualCall(node, node.interfaceTarget,
+          (signature) => wrap(node.receiver, signature.inputs.first),
+          (signature) {
+        w.ValueType paramType = signature.inputs.last;
+        wrap(node.value, paramType);
+        if (preserved) {
+          temp = addLocal(paramType);
+          b.local_tee(temp!);
+        }
+      }, getter: false, setter: true);
+      if (preserved) {
+        b.local_get(temp!);
+        return temp!.type;
+      } else {
+        return voidMarker;
+      }
+    }
+  }
+
+  w.ValueType _directSet(Member target, Expression receiver, Expression value,
+      {required bool preserved}) {
+    w.Local? temp;
+    if (target is Field) {
+      ClassInfo info = translator.classInfo[target.enclosingClass]!;
+      int fieldIndex = translator.fieldIndex[target]!;
+      w.ValueType receiverType = info.nullableType;
+      w.ValueType fieldType = info.struct.fields[fieldIndex].type.unpacked;
+      wrap(receiver, receiverType);
+      wrap(value, fieldType);
+      if (preserved) {
+        temp = addLocal(fieldType);
+        b.local_tee(temp);
+      }
+      b.struct_set(info.struct, fieldIndex);
+    } else {
+      w.BaseFunction targetFunction =
+          translator.functions.getFunction(target.reference);
+      w.ValueType paramType = targetFunction.type.inputs.last;
+      wrap(receiver, targetFunction.type.inputs.first);
+      wrap(value, paramType);
+      if (preserved) {
+        temp = addLocal(paramType);
+        b.local_tee(temp);
+        translator.convertType(function, temp.type, paramType);
+      }
+      _call(target.reference);
+    }
+    if (preserved) {
+      b.local_get(temp!);
+      return temp.type;
+    } else {
+      return voidMarker;
+    }
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    Capture? capture = closures.captures[node.variable];
+    bool locallyClosurized = closures.closurizedFunctions.contains(node);
+    if (capture != null || locallyClosurized) {
+      if (capture != null) {
+        b.local_get(capture.context.currentLocal);
+      }
+      w.StructType struct = _instantiateClosure(node.function);
+      if (locallyClosurized) {
+        w.Local local = addLocal(w.RefType.def(struct, nullable: false));
+        locals[node.variable] = local;
+        if (capture != null) {
+          b.local_tee(local);
+        } else {
+          b.local_set(local);
+        }
+      }
+      if (capture != null) {
+        b.struct_set(capture.context.struct, capture.fieldIndex);
+      }
+    }
+  }
+
+  @override
+  w.ValueType visitFunctionExpression(
+      FunctionExpression node, w.ValueType expectedType) {
+    w.StructType struct = _instantiateClosure(node.function);
+    return w.RefType.def(struct, nullable: false);
+  }
+
+  w.StructType _instantiateClosure(FunctionNode functionNode) {
+    int parameterCount = functionNode.requiredParameterCount;
+    Lambda lambda = closures.lambdas[functionNode]!;
+    w.DefinedGlobal global = translator.makeFunctionRef(lambda.function);
+
+    ClassInfo info = translator.classInfo[translator.functionClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.StructType struct = translator.closureStructType(parameterCount);
+
+    b.i32_const(info.classId);
+    b.i32_const(initialIdentityHash);
+    _pushContext(functionNode);
+    b.global_get(global);
+    translator.struct_new(b, parameterCount);
+
+    return struct;
+  }
+
+  void _pushContext(FunctionNode functionNode) {
+    Context? context = closures.contexts[functionNode]?.parent;
+    if (context != null) {
+      b.local_get(context.currentLocal);
+      if (context.currentLocal.type.nullable) {
+        b.ref_as_non_null();
+      }
+    } else {
+      b.global_get(translator.globals.dummyGlobal); // Dummy context
+    }
+  }
+
+  @override
+  w.ValueType visitFunctionInvocation(
+      FunctionInvocation node, w.ValueType expectedType) {
+    FunctionType functionType = node.functionType!;
+    int parameterCount = functionType.requiredParameterCount;
+    return _functionCall(parameterCount, node.receiver, node.arguments);
+  }
+
+  w.ValueType _functionCall(
+      int parameterCount, Expression receiver, Arguments arguments) {
+    w.StructType struct = translator.closureStructType(parameterCount);
+    w.Local temp = addLocal(w.RefType.def(struct, nullable: false));
+    wrap(receiver, temp.type);
+    b.local_tee(temp);
+    b.struct_get(struct, FieldIndex.closureContext);
+    for (Expression arg in arguments.positional) {
+      wrap(arg, translator.topInfo.nullableType);
+    }
+    b.local_get(temp);
+    b.struct_get(struct, FieldIndex.closureFunction);
+    b.call_ref();
+    return translator.topInfo.nullableType;
+  }
+
+  @override
+  w.ValueType visitLocalFunctionInvocation(
+      LocalFunctionInvocation node, w.ValueType expectedType) {
+    var decl = node.variable.parent as FunctionDeclaration;
+    _pushContext(decl.function);
+    for (Expression arg in node.arguments.positional) {
+      wrap(arg, translator.topInfo.nullableType);
+    }
+    Lambda lambda = closures.lambdas[decl.function]!;
+    b.comment("Local call of ${decl.variable.name}");
+    b.call(lambda.function);
+    return translator.topInfo.nullableType;
+  }
+
+  @override
+  w.ValueType visitLogicalExpression(
+      LogicalExpression node, w.ValueType expectedType) {
+    _conditional(node, () => b.i32_const(1), () => b.i32_const(0),
+        const [w.NumType.i32]);
+    return w.NumType.i32;
+  }
+
+  @override
+  w.ValueType visitNot(Not node, w.ValueType expectedType) {
+    wrap(node.operand, w.NumType.i32);
+    b.i32_eqz();
+    return w.NumType.i32;
+  }
+
+  @override
+  w.ValueType visitConditionalExpression(
+      ConditionalExpression node, w.ValueType expectedType) {
+    _conditional(
+        node.condition,
+        () => wrap(node.then, expectedType),
+        () => wrap(node.otherwise, expectedType),
+        [if (expectedType != voidMarker) expectedType]);
+    return expectedType;
+  }
+
+  @override
+  w.ValueType visitNullCheck(NullCheck node, w.ValueType expectedType) {
+    // TODO(joshualitt): Check and throw exception
+    return wrap(node.operand, expectedType);
+  }
+
+  void _visitArguments(Arguments node, Reference target, int signatureOffset) {
+    final w.FunctionType signature = translator.signatureFor(target);
+    final ParameterInfo paramInfo = translator.paramInfoFor(target);
+    for (int i = 0; i < node.types.length; i++) {
+      _makeType(node.types[i], node);
+    }
+    signatureOffset += node.types.length;
+    for (int i = 0; i < node.positional.length; i++) {
+      wrap(node.positional[i], signature.inputs[signatureOffset + i]);
+    }
+    // Default values for positional parameters
+    for (int i = node.positional.length; i < paramInfo.positional.length; i++) {
+      final w.ValueType type = signature.inputs[signatureOffset + i];
+      translator.constants
+          .instantiateConstant(function, b, paramInfo.positional[i]!, type);
+    }
+    // Named arguments
+    final Map<String, w.Local> namedLocals = {};
+    for (var namedArg in node.named) {
+      final w.ValueType type = signature
+          .inputs[signatureOffset + paramInfo.nameIndex[namedArg.name]!];
+      final w.Local namedLocal = addLocal(type);
+      namedLocals[namedArg.name] = namedLocal;
+      wrap(namedArg.value, namedLocal.type);
+      b.local_set(namedLocal);
+    }
+    for (String name in paramInfo.names) {
+      w.Local? namedLocal = namedLocals[name];
+      final w.ValueType type =
+          signature.inputs[signatureOffset + paramInfo.nameIndex[name]!];
+      if (namedLocal != null) {
+        b.local_get(namedLocal);
+        translator.convertType(function, namedLocal.type, type);
+      } else {
+        translator.constants
+            .instantiateConstant(function, b, paramInfo.named[name]!, type);
+      }
+    }
+  }
+
+  @override
+  w.ValueType visitStringConcatenation(
+      StringConcatenation node, w.ValueType expectedType) {
+    _makeList(
+        node.expressions,
+        translator.fixedLengthListClass,
+        InterfaceType(translator.stringBaseClass, Nullability.nonNullable),
+        node);
+    return _call(translator.stringInterpolate.reference);
+  }
+
+  @override
+  w.ValueType visitThrow(Throw node, w.ValueType expectedType) {
+    wrap(node.expression, translator.topInfo.nullableType);
+    // TODO(joshualitt): Throw exception
+    b.comment(node.toStringInternal());
+    b.drop();
+    b.block(const [], [if (expectedType != voidMarker) expectedType]);
+    b.unreachable();
+    b.end();
+    return expectedType;
+  }
+
+  @override
+  w.ValueType visitInstantiation(Instantiation node, w.ValueType expectedType) {
+    throw "Not supported: Generic function instantiation at ${node.location}";
+  }
+
+  @override
+  w.ValueType visitConstantExpression(
+      ConstantExpression node, w.ValueType expectedType) {
+    translator.constants
+        .instantiateConstant(function, b, node.constant, expectedType);
+    return expectedType;
+  }
+
+  @override
+  w.ValueType visitNullLiteral(NullLiteral node, w.ValueType expectedType) {
+    translator.constants
+        .instantiateConstant(function, b, NullConstant(), expectedType);
+    return expectedType;
+  }
+
+  @override
+  w.ValueType visitStringLiteral(StringLiteral node, w.ValueType expectedType) {
+    translator.constants.instantiateConstant(
+        function, b, StringConstant(node.value), expectedType);
+    return expectedType;
+  }
+
+  @override
+  w.ValueType visitBoolLiteral(BoolLiteral node, w.ValueType expectedType) {
+    b.i32_const(node.value ? 1 : 0);
+    return w.NumType.i32;
+  }
+
+  @override
+  w.ValueType visitIntLiteral(IntLiteral node, w.ValueType expectedType) {
+    b.i64_const(node.value);
+    return w.NumType.i64;
+  }
+
+  @override
+  w.ValueType visitDoubleLiteral(DoubleLiteral node, w.ValueType expectedType) {
+    b.f64_const(node.value);
+    return w.NumType.f64;
+  }
+
+  @override
+  w.ValueType visitListLiteral(ListLiteral node, w.ValueType expectedType) {
+    return _makeList(node.expressions, translator.growableListClass,
+        node.typeArgument, node);
+  }
+
+  w.ValueType _makeList(List<Expression> expressions, Class cls,
+      DartType typeArg, TreeNode node) {
+    ClassInfo info = translator.classInfo[cls]!;
+    translator.functions.allocateClass(info.classId);
+    w.RefType refType = info.struct.fields.last.type.unpacked as w.RefType;
+    w.ArrayType arrayType = refType.heapType as w.ArrayType;
+    w.ValueType elementType = arrayType.elementType.type.unpacked;
+    int length = expressions.length;
+
+    b.i32_const(info.classId);
+    b.i32_const(initialIdentityHash);
+    _makeType(typeArg, node);
+    b.i64_const(length);
+    if (options.lazyConstants) {
+      // Avoid array.init instruction in lazy constants mode
+      b.i32_const(length);
+      translator.array_new_default(b, arrayType);
+      if (length > 0) {
+        w.Local arrayLocal = addLocal(refType.withNullability(false));
+        b.local_set(arrayLocal);
+        for (int i = 0; i < length; i++) {
+          b.local_get(arrayLocal);
+          b.i32_const(i);
+          wrap(expressions[i], elementType);
+          b.array_set(arrayType);
+        }
+        b.local_get(arrayLocal);
+        if (arrayLocal.type.nullable) {
+          b.ref_as_non_null();
+        }
+      }
+    } else {
+      for (Expression expression in expressions) {
+        wrap(expression, elementType);
+      }
+      translator.array_init(b, arrayType, length);
+    }
+    translator.struct_new(b, info);
+
+    return info.nonNullableType;
+  }
+
+  @override
+  w.ValueType visitMapLiteral(MapLiteral node, w.ValueType expectedType) {
+    w.BaseFunction mapFactory =
+        translator.functions.getFunction(translator.mapFactory.reference);
+    w.ValueType factoryReturnType = mapFactory.type.outputs.single;
+    _makeType(node.keyType, node);
+    _makeType(node.valueType, node);
+    b.call(mapFactory);
+    if (node.entries.isEmpty) {
+      return factoryReturnType;
+    }
+    w.BaseFunction mapPut =
+        translator.functions.getFunction(translator.mapPut.reference);
+    w.ValueType putReceiverType = mapPut.type.inputs[0];
+    w.ValueType putKeyType = mapPut.type.inputs[1];
+    w.ValueType putValueType = mapPut.type.inputs[2];
+    w.Local mapLocal = addLocal(putReceiverType);
+    translator.convertType(function, factoryReturnType, mapLocal.type);
+    b.local_set(mapLocal);
+    for (MapLiteralEntry entry in node.entries) {
+      b.local_get(mapLocal);
+      translator.convertType(function, mapLocal.type, putReceiverType);
+      wrap(entry.key, putKeyType);
+      wrap(entry.value, putValueType);
+      b.call(mapPut);
+    }
+    b.local_get(mapLocal);
+    return mapLocal.type;
+  }
+
+  @override
+  w.ValueType visitTypeLiteral(TypeLiteral node, w.ValueType expectedType) {
+    return _makeType(node.type, node);
+  }
+
+  w.ValueType _makeType(DartType type, TreeNode node) {
+    w.ValueType typeType =
+        translator.classInfo[translator.typeClass]!.nullableType;
+    if (_isTypeConstant(type)) {
+      return wrap(ConstantExpression(TypeLiteralConstant(type)), typeType);
+    }
+    if (type is TypeParameterType) {
+      if (type.parameter.parent is FunctionNode) {
+        // Type argument to function
+        w.Local? local = typeLocals[type.parameter];
+        if (local != null) {
+          b.local_get(local);
+          return local.type;
+        } else {
+          _unimplemented(
+              node, "Type parameter access inside lambda", [typeType]);
+          return typeType;
+        }
+      }
+      // Type argument of class
+      Class cls = type.parameter.parent as Class;
+      ClassInfo info = translator.classInfo[cls]!;
+      int fieldIndex = translator.typeParameterIndex[type.parameter]!;
+      w.ValueType thisType = _visitThis(info.nullableType);
+      translator.convertType(function, thisType, info.nullableType);
+      b.struct_get(info.struct, fieldIndex);
+      return typeType;
+    }
+    ClassInfo info = translator.classInfo[translator.typeClass]!;
+    translator.functions.allocateClass(info.classId);
+    if (type is FutureOrType) {
+      // TODO(askesc): Have an actual representation of FutureOr types
+      b.ref_null(info.nullableType.heapType);
+      return info.nullableType;
+    }
+    if (type is! InterfaceType) {
+      _unimplemented(node, type, [info.nullableType]);
+      return info.nullableType;
+    }
+    ClassInfo typeInfo = translator.classInfo[type.classNode]!;
+    w.ValueType typeListExpectedType = info.struct.fields[3].type.unpacked;
+    b.i32_const(info.classId);
+    b.i32_const(initialIdentityHash);
+    b.i64_const(typeInfo.classId);
+    if (type.typeArguments.isEmpty) {
+      b.global_get(translator.constants.emptyTypeList);
+      translator.convertType(function,
+          translator.constants.emptyTypeList.type.type, typeListExpectedType);
+    } else if (type.typeArguments.every(_isTypeConstant)) {
+      ListConstant typeArgs = ListConstant(
+          InterfaceType(translator.typeClass, Nullability.nonNullable),
+          type.typeArguments.map((t) => TypeLiteralConstant(t)).toList());
+      translator.constants
+          .instantiateConstant(function, b, typeArgs, typeListExpectedType);
+    } else {
+      w.ValueType listType = _makeList(
+          type.typeArguments.map((t) => TypeLiteral(t)).toList(),
+          translator.fixedLengthListClass,
+          InterfaceType(translator.typeClass, Nullability.nonNullable),
+          node);
+      translator.convertType(function, listType, typeListExpectedType);
+    }
+    translator.struct_new(b, info);
+    return info.nullableType;
+  }
+
+  bool _isTypeConstant(DartType type) {
+    return type is DynamicType ||
+        type is VoidType ||
+        type is NeverType ||
+        type is NullType ||
+        type is FunctionType ||
+        type is InterfaceType && type.typeArguments.every(_isTypeConstant);
+  }
+
+  @override
+  w.ValueType visitIsExpression(IsExpression node, w.ValueType expectedType) {
+    wrap(node.operand, translator.topInfo.nullableType);
+    emitTypeTest(node.type, dartTypeOf(node.operand), node);
+    return w.NumType.i32;
+  }
+
+  /// Test value against a Dart type. Expects the value on the stack as a
+  /// (ref null #Top) and leaves the result on the stack as an i32.
+  void emitTypeTest(DartType type, DartType operandType, TreeNode node) {
+    if (type is! InterfaceType) {
+      // TODO(askesc): Implement type test for remaining types
+      print("Not implemented: Type test with non-interface type $type"
+          " at ${node.location}");
+      b.drop();
+      b.i32_const(1);
+      return;
+    }
+    bool isNullable = operandType.isPotentiallyNullable;
+    w.Label? resultLabel;
+    if (isNullable) {
+      // Store operand in a temporary variable, since Binaryen does not support
+      // block inputs.
+      w.Local operand = addLocal(translator.topInfo.nullableType);
+      b.local_set(operand);
+      resultLabel = b.block(const [], const [w.NumType.i32]);
+      w.Label nullLabel = b.block(const [], const []);
+      b.local_get(operand);
+      b.br_on_null(nullLabel);
+    }
+    if (type.typeArguments.any((t) => t is! DynamicType)) {
+      // If the tested-against type as an instance of the static operand type
+      // has the same type arguments as the static operand type, it is not
+      // necessary to test the type arguments.
+      Class cls = translator.classForType(operandType);
+      InterfaceType? base = translator.hierarchy
+          .getTypeAsInstanceOf(type, cls, member.enclosingLibrary)
+          ?.withDeclaredNullability(operandType.declaredNullability);
+      if (base != operandType) {
+        print("Not implemented: Type test with type arguments"
+            " at ${node.location}");
+      }
+    }
+    List<Class> concrete = translator.subtypes
+        .getSubtypesOf(type.classNode)
+        .where((c) => !c.isAbstract)
+        .toList();
+    if (concrete.isEmpty) {
+      b.drop();
+      b.i32_const(0);
+    } else if (concrete.length == 1) {
+      ClassInfo info = translator.classInfo[concrete.single]!;
+      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+      b.i32_const(info.classId);
+      b.i32_eq();
+    } else {
+      w.Local idLocal = addLocal(w.NumType.i32);
+      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+      b.local_set(idLocal);
+      w.Label done = b.block(const [], const [w.NumType.i32]);
+      b.i32_const(1);
+      for (Class cls in concrete) {
+        ClassInfo info = translator.classInfo[cls]!;
+        b.i32_const(info.classId);
+        b.local_get(idLocal);
+        b.i32_eq();
+        b.br_if(done);
+      }
+      b.drop();
+      b.i32_const(0);
+      b.end(); // done
+    }
+    if (isNullable) {
+      b.br(resultLabel!);
+      b.end(); // nullLabel
+      b.i32_const(type.declaredNullability == Nullability.nullable ? 1 : 0);
+      b.end(); // resultLabel
+    }
+  }
+
+  @override
+  w.ValueType visitAsExpression(AsExpression node, w.ValueType expectedType) {
+    // TODO(joshualitt): Emit type test and throw exception on failure
+    return wrap(node.operand, expectedType);
+  }
+}
diff --git a/pkg/dart2wasm/lib/compile.dart b/pkg/dart2wasm/lib/compile.dart
new file mode 100644
index 0000000..c69fdab
--- /dev/null
+++ b/pkg/dart2wasm/lib/compile.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2022, 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 'dart:typed_data';
+
+import 'package:front_end/src/api_unstable/vm.dart'
+    show
+        CompilerOptions,
+        CompilerResult,
+        DiagnosticMessage,
+        kernelForProgram,
+        Severity;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/type_environment.dart';
+
+import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
+    show transformComponent;
+
+import 'package:dart2wasm/target.dart';
+import 'package:dart2wasm/translator.dart';
+
+/// Compile a Dart file into a Wasm module.
+///
+/// Returns `null` if an error occurred during compilation. The
+/// [handleDiagnosticMessage] callback will have received an error message
+/// describing the error.
+Future<Uint8List?> compileToModule(
+    Uri mainUri,
+    Uri sdkRoot,
+    TranslatorOptions options,
+    void Function(DiagnosticMessage) handleDiagnosticMessage) async {
+  var succeeded = true;
+  void diagnosticMessageHandler(DiagnosticMessage message) {
+    if (message.severity == Severity.error) {
+      succeeded = false;
+    }
+    handleDiagnosticMessage(message);
+  }
+
+  Target target = WasmTarget();
+  CompilerOptions compilerOptions = CompilerOptions()
+    ..target = target
+    ..compileSdk = true
+    ..sdkRoot = sdkRoot
+    ..environmentDefines = {}
+    ..verbose = false
+    ..onDiagnostic = diagnosticMessageHandler;
+
+  CompilerResult? compilerResult =
+      await kernelForProgram(mainUri, compilerOptions);
+  if (compilerResult == null || !succeeded) {
+    return null;
+  }
+  Component component = compilerResult.component!;
+  CoreTypes coreTypes = compilerResult.coreTypes!;
+
+  globalTypeFlow.transformComponent(target, coreTypes, component,
+      treeShakeSignatures: true,
+      treeShakeWriteOnlyFields: true,
+      useRapidTypeAnalysis: false);
+
+  var translator = Translator(component, coreTypes,
+      TypeEnvironment(coreTypes, compilerResult.classHierarchy!), options);
+  return translator.translate();
+}
diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart
new file mode 100644
index 0000000..789f070
--- /dev/null
+++ b/pkg/dart2wasm/lib/constants.dart
@@ -0,0 +1,637 @@
+// Copyright (c) 2022, 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 'dart:typed_data';
+
+import 'package:dart2wasm/class_info.dart';
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/type_algebra.dart' show substitute;
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+class ConstantInfo {
+  final Constant constant;
+  final w.DefinedGlobal global;
+  final w.DefinedFunction? function;
+
+  ConstantInfo(this.constant, this.global, this.function);
+}
+
+typedef ConstantCodeGenerator = void Function(
+    w.DefinedFunction?, w.Instructions);
+
+/// Handles the creation of Dart constants. Can operate in two modes - eager and
+/// lazy - controlled by [TranslatorOptions.lazyConstants].
+///
+/// Each (non-trivial) constant is assigned to a Wasm global. Multiple
+/// occurrences of the same constant use the same global.
+///
+/// In eager mode, the constant is contained within the global initializer,
+/// meaning all constants are initialized eagerly during module initialization.
+/// In lazy mode, the global starts out uninitialized, and every use of the
+/// constant checks the global to see if it has been initialized and calls an
+/// initialization function otherwise.
+class Constants {
+  final Translator translator;
+  final Map<Constant, ConstantInfo> constantInfo = {};
+  final StringBuffer oneByteStrings = StringBuffer();
+  final StringBuffer twoByteStrings = StringBuffer();
+  late final w.DefinedFunction oneByteStringFunction;
+  late final w.DefinedFunction twoByteStringFunction;
+  late final w.DataSegment oneByteStringSegment;
+  late final w.DataSegment twoByteStringSegment;
+  late final w.DefinedGlobal emptyString;
+  late final w.DefinedGlobal emptyTypeList;
+  late final ClassInfo typeInfo = translator.classInfo[translator.typeClass]!;
+
+  bool currentlyCreating = false;
+
+  Constants(this.translator) {
+    if (lazyConstants) {
+      oneByteStringFunction = makeStringFunction(translator.oneByteStringClass);
+      twoByteStringFunction = makeStringFunction(translator.twoByteStringClass);
+    } else if (stringDataSegments) {
+      oneByteStringSegment = m.addDataSegment();
+      twoByteStringSegment = m.addDataSegment();
+    }
+    initEmptyString();
+    initEmptyTypeList();
+  }
+
+  w.Module get m => translator.m;
+  bool get lazyConstants => translator.options.lazyConstants;
+  bool get stringDataSegments => translator.options.stringDataSegments;
+
+  void initEmptyString() {
+    ClassInfo info = translator.classInfo[translator.oneByteStringClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.ArrayType arrayType =
+        (info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
+
+    if (lazyConstants) {
+      w.RefType emptyStringType = info.nullableType;
+      emptyString = m.addGlobal(w.GlobalType(emptyStringType));
+      emptyString.initializer.ref_null(emptyStringType.heapType);
+      emptyString.initializer.end();
+
+      w.Instructions b = translator.initFunction.body;
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.i32_const(0);
+      translator.array_new_default(b, arrayType);
+      translator.struct_new(b, info);
+      b.global_set(emptyString);
+    } else {
+      w.RefType emptyStringType = info.nonNullableType;
+      emptyString = m.addGlobal(w.GlobalType(emptyStringType, mutable: false));
+      w.Instructions ib = emptyString.initializer;
+      ib.i32_const(info.classId);
+      ib.i32_const(initialIdentityHash);
+      translator.array_init(ib, arrayType, 0);
+      translator.struct_new(ib, info);
+      ib.end();
+    }
+
+    Constant emptyStringConstant = StringConstant("");
+    constantInfo[emptyStringConstant] =
+        ConstantInfo(emptyStringConstant, emptyString, null);
+  }
+
+  void initEmptyTypeList() {
+    ClassInfo info = translator.classInfo[translator.immutableListClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.RefType refType = info.struct.fields.last.type.unpacked as w.RefType;
+    w.ArrayType arrayType = refType.heapType as w.ArrayType;
+
+    // Create the empty type list with its type parameter uninitialized for now.
+    if (lazyConstants) {
+      w.RefType emptyListType = info.nullableType;
+      emptyTypeList = m.addGlobal(w.GlobalType(emptyListType));
+      emptyTypeList.initializer.ref_null(emptyListType.heapType);
+      emptyTypeList.initializer.end();
+
+      w.Instructions b = translator.initFunction.body;
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.ref_null(typeInfo.struct); // Initialized later
+      b.i64_const(0);
+      b.i32_const(0);
+      translator.array_new_default(b, arrayType);
+      translator.struct_new(b, info);
+      b.global_set(emptyTypeList);
+    } else {
+      w.RefType emptyListType = info.nonNullableType;
+      emptyTypeList = m.addGlobal(w.GlobalType(emptyListType, mutable: false));
+      w.Instructions ib = emptyTypeList.initializer;
+      ib.i32_const(info.classId);
+      ib.i32_const(initialIdentityHash);
+      ib.ref_null(typeInfo.struct); // Initialized later
+      ib.i64_const(0);
+      translator.array_init(ib, arrayType, 0);
+      translator.struct_new(ib, info);
+      ib.end();
+    }
+
+    Constant emptyTypeListConstant = ListConstant(
+        InterfaceType(translator.typeClass, Nullability.nonNullable), const []);
+    constantInfo[emptyTypeListConstant] =
+        ConstantInfo(emptyTypeListConstant, emptyTypeList, null);
+
+    // Initialize the type parameter of the empty type list to the type object
+    // for _Type, which itself refers to the empty type list.
+    w.Instructions b = translator.initFunction.body;
+    b.global_get(emptyTypeList);
+    instantiateConstant(
+        translator.initFunction,
+        b,
+        TypeLiteralConstant(
+            InterfaceType(translator.typeClass, Nullability.nonNullable)),
+        typeInfo.nullableType);
+    b.struct_set(info.struct,
+        translator.typeParameterIndex[info.cls!.typeParameters.single]!);
+  }
+
+  void finalize() {
+    if (lazyConstants) {
+      finalizeStrings();
+    }
+  }
+
+  void finalizeStrings() {
+    Uint8List oneByteStringsAsBytes =
+        Uint8List.fromList(oneByteStrings.toString().codeUnits);
+    assert(Endian.host == Endian.little);
+    Uint8List twoByteStringsAsBytes =
+        Uint16List.fromList(twoByteStrings.toString().codeUnits)
+            .buffer
+            .asUint8List();
+    Uint8List stringsAsBytes = (BytesBuilder()
+          ..add(twoByteStringsAsBytes)
+          ..add(oneByteStringsAsBytes))
+        .toBytes();
+
+    w.Memory stringMemory =
+        m.addMemory(stringsAsBytes.length, stringsAsBytes.length);
+    m.addDataSegment(stringsAsBytes, stringMemory, 0);
+    makeStringFunctionBody(translator.oneByteStringClass, oneByteStringFunction,
+        (b) {
+      b.i32_load8_u(stringMemory, twoByteStringsAsBytes.length);
+    });
+    makeStringFunctionBody(translator.twoByteStringClass, twoByteStringFunction,
+        (b) {
+      b.i32_const(1);
+      b.i32_shl();
+      b.i32_load16_u(stringMemory, 0);
+    });
+  }
+
+  /// Create one of the two Wasm functions (one for each string type) called
+  /// from every lazily initialized string constant (of that type) to create and
+  /// initialize the string.
+  ///
+  /// The function signature is (i32 offset, i32 length) -> (ref stringClass)
+  /// where offset and length are measured in characters and indicate the place
+  /// in the corresponding string data segment from which to copy this string.
+  w.DefinedFunction makeStringFunction(Class cls) {
+    ClassInfo info = translator.classInfo[cls]!;
+    w.FunctionType ftype = translator.functionType(
+        const [w.NumType.i32, w.NumType.i32], [info.nonNullableType]);
+    return m.addFunction(ftype, "makeString (${cls.name})");
+  }
+
+  void makeStringFunctionBody(Class cls, w.DefinedFunction function,
+      void Function(w.Instructions) emitLoad) {
+    ClassInfo info = translator.classInfo[cls]!;
+    w.ArrayType arrayType =
+        (info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
+
+    w.Local offset = function.locals[0];
+    w.Local length = function.locals[1];
+    w.Local array = function.addLocal(
+        translator.typeForLocal(w.RefType.def(arrayType, nullable: false)));
+    w.Local index = function.addLocal(w.NumType.i32);
+
+    w.Instructions b = function.body;
+    b.local_get(length);
+    translator.array_new_default(b, arrayType);
+    b.local_set(array);
+
+    b.i32_const(0);
+    b.local_set(index);
+    w.Label loop = b.loop();
+    b.local_get(array);
+    b.local_get(index);
+    b.local_get(offset);
+    b.local_get(index);
+    b.i32_add();
+    emitLoad(b);
+    b.array_set(arrayType);
+    b.local_get(index);
+    b.i32_const(1);
+    b.i32_add();
+    b.local_tee(index);
+    b.local_get(length);
+    b.i32_lt_u();
+    b.br_if(loop);
+    b.end();
+
+    b.i32_const(info.classId);
+    b.i32_const(initialIdentityHash);
+    b.local_get(array);
+    translator.struct_new(b, info);
+    b.end();
+  }
+
+  /// Ensure that the constant has a Wasm global assigned.
+  ///
+  /// In eager mode, sub-constants must have Wasm globals assigned before the
+  /// global for the composite constant is assigned, since global initializers
+  /// can only refer to earlier globals.
+  void ensureConstant(Constant constant) {
+    ConstantCreator(this).ensureConstant(constant);
+  }
+
+  /// Emit code to push a constant onto the stack.
+  void instantiateConstant(w.DefinedFunction? function, w.Instructions b,
+      Constant constant, w.ValueType expectedType) {
+    if (expectedType == translator.voidMarker) return;
+    ConstantInstantiator(this, function, b, expectedType).instantiate(constant);
+  }
+}
+
+class ConstantInstantiator extends ConstantVisitor<w.ValueType> {
+  final Constants constants;
+  final w.DefinedFunction? function;
+  final w.Instructions b;
+  final w.ValueType expectedType;
+
+  ConstantInstantiator(
+      this.constants, this.function, this.b, this.expectedType);
+
+  Translator get translator => constants.translator;
+  w.Module get m => translator.m;
+
+  void instantiate(Constant constant) {
+    w.ValueType resultType = constant.accept(this);
+    assert(!translator.needsConversion(resultType, expectedType),
+        "For $constant: expected $expectedType, got $resultType");
+  }
+
+  @override
+  w.ValueType defaultConstant(Constant constant) {
+    ConstantInfo info = ConstantCreator(constants).ensureConstant(constant)!;
+    w.ValueType globalType = info.global.type.type;
+    if (globalType.nullable) {
+      if (info.function != null) {
+        // Lazily initialized constant.
+        w.Label done = b.block(const [], [globalType.withNullability(false)]);
+        b.global_get(info.global);
+        b.br_on_non_null(done);
+        b.call(info.function!);
+        b.end();
+      } else {
+        // Constant initialized in the module init function.
+        b.global_get(info.global);
+        b.ref_as_non_null();
+      }
+      return globalType.withNullability(false);
+    } else {
+      // Constant initialized eagerly in a global initializer.
+      b.global_get(info.global);
+      return globalType;
+    }
+  }
+
+  @override
+  w.ValueType visitNullConstant(NullConstant node) {
+    w.ValueType? expectedType = this.expectedType;
+    if (expectedType != translator.voidMarker) {
+      if (expectedType.nullable) {
+        w.HeapType heapType =
+            expectedType is w.RefType ? expectedType.heapType : w.HeapType.data;
+        b.ref_null(heapType);
+      } else {
+        // This only happens in invalid but unreachable code produced by the
+        // TFA dead-code elimination.
+        b.comment("Non-nullable null constant");
+        b.block(const [], [expectedType]);
+        b.unreachable();
+        b.end();
+      }
+    }
+    return expectedType;
+  }
+
+  w.ValueType _maybeBox(w.ValueType wasmType, void Function() pushValue) {
+    if (expectedType is w.RefType) {
+      ClassInfo info = translator.classInfo[translator.boxedClasses[wasmType]]!;
+      b.i32_const(info.classId);
+      pushValue();
+      translator.struct_new(b, info);
+      return info.nonNullableType;
+    } else {
+      pushValue();
+      return wasmType;
+    }
+  }
+
+  @override
+  w.ValueType visitBoolConstant(BoolConstant constant) {
+    return _maybeBox(w.NumType.i32, () {
+      b.i32_const(constant.value ? 1 : 0);
+    });
+  }
+
+  @override
+  w.ValueType visitIntConstant(IntConstant constant) {
+    return _maybeBox(w.NumType.i64, () {
+      b.i64_const(constant.value);
+    });
+  }
+
+  @override
+  w.ValueType visitDoubleConstant(DoubleConstant constant) {
+    return _maybeBox(w.NumType.f64, () {
+      b.f64_const(constant.value);
+    });
+  }
+}
+
+class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
+  final Constants constants;
+
+  ConstantCreator(this.constants);
+
+  Translator get translator => constants.translator;
+  w.Module get m => constants.m;
+  bool get lazyConstants => constants.lazyConstants;
+
+  ConstantInfo? ensureConstant(Constant constant) {
+    ConstantInfo? info = constants.constantInfo[constant];
+    if (info == null) {
+      info = constant.accept(this);
+      if (info != null) {
+        constants.constantInfo[constant] = info;
+      }
+    }
+    return info;
+  }
+
+  ConstantInfo createConstant(
+      Constant constant, w.RefType type, ConstantCodeGenerator generator) {
+    assert(!type.nullable);
+    if (lazyConstants) {
+      // Create uninitialized global and function to initialize it.
+      w.DefinedGlobal global =
+          m.addGlobal(w.GlobalType(type.withNullability(true)));
+      global.initializer.ref_null(type.heapType);
+      global.initializer.end();
+      w.FunctionType ftype = translator.functionType(const [], [type]);
+      w.DefinedFunction function = m.addFunction(ftype, "$constant");
+      generator(function, function.body);
+      w.Local temp = function.addLocal(translator.typeForLocal(type));
+      w.Instructions b2 = function.body;
+      b2.local_tee(temp);
+      b2.global_set(global);
+      b2.local_get(temp);
+      translator.convertType(function, temp.type, type);
+      b2.end();
+
+      return ConstantInfo(constant, global, function);
+    } else {
+      // Create global with the constant in its initializer.
+      assert(!constants.currentlyCreating);
+      constants.currentlyCreating = true;
+      w.DefinedGlobal global = m.addGlobal(w.GlobalType(type, mutable: false));
+      generator(null, global.initializer);
+      global.initializer.end();
+      constants.currentlyCreating = false;
+
+      return ConstantInfo(constant, global, null);
+    }
+  }
+
+  @override
+  ConstantInfo? defaultConstant(Constant constant) => null;
+
+  @override
+  ConstantInfo? visitStringConstant(StringConstant constant) {
+    bool isOneByte = constant.value.codeUnits.every((c) => c <= 255);
+    ClassInfo info = translator.classInfo[isOneByte
+        ? translator.oneByteStringClass
+        : translator.twoByteStringClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.RefType type = info.nonNullableType;
+    return createConstant(constant, type, (function, b) {
+      if (lazyConstants) {
+        // Copy string contents from linear memory on initialization. The memory
+        // is initialized by an active data segment for each string type.
+        StringBuffer buffer =
+            isOneByte ? constants.oneByteStrings : constants.twoByteStrings;
+        int offset = buffer.length;
+        int length = constant.value.length;
+        buffer.write(constant.value);
+
+        b.i32_const(offset);
+        b.i32_const(length);
+        b.call(isOneByte
+            ? constants.oneByteStringFunction
+            : constants.twoByteStringFunction);
+      } else {
+        w.ArrayType arrayType =
+            (info.struct.fields.last.type as w.RefType).heapType as w.ArrayType;
+
+        b.i32_const(info.classId);
+        b.i32_const(initialIdentityHash);
+        if (constants.stringDataSegments) {
+          // Initialize string contents from passive data segment.
+          w.DataSegment segment;
+          Uint8List bytes;
+          if (isOneByte) {
+            segment = constants.oneByteStringSegment;
+            bytes = Uint8List.fromList(constant.value.codeUnits);
+          } else {
+            assert(Endian.host == Endian.little);
+            segment = constants.twoByteStringSegment;
+            bytes = Uint16List.fromList(constant.value.codeUnits)
+                .buffer
+                .asUint8List();
+          }
+          int offset = segment.length;
+          segment.append(bytes);
+          b.i32_const(offset);
+          b.i32_const(constant.value.length);
+          translator.array_init_from_data(b, arrayType, segment);
+        } else {
+          // Initialize string contents from i32 constants on the stack.
+          for (int charCode in constant.value.codeUnits) {
+            b.i32_const(charCode);
+          }
+          translator.array_init(b, arrayType, constant.value.length);
+        }
+        translator.struct_new(b, info);
+      }
+    });
+  }
+
+  @override
+  ConstantInfo? visitInstanceConstant(InstanceConstant constant) {
+    Class cls = constant.classNode;
+    ClassInfo info = translator.classInfo[cls]!;
+    translator.functions.allocateClass(info.classId);
+    w.RefType type = info.nonNullableType;
+
+    // Collect sub-constants for field values.
+    const int baseFieldCount = 2;
+    int fieldCount = info.struct.fields.length;
+    List<Constant?> subConstants = List.filled(fieldCount, null);
+    constant.fieldValues.forEach((reference, subConstant) {
+      int index = translator.fieldIndex[reference.asField]!;
+      assert(subConstants[index] == null);
+      subConstants[index] = subConstant;
+      ensureConstant(subConstant);
+    });
+
+    // Collect sub-constants for type arguments.
+    Map<TypeParameter, DartType> substitution = {};
+    List<DartType> args = constant.typeArguments;
+    while (true) {
+      for (int i = 0; i < cls.typeParameters.length; i++) {
+        TypeParameter parameter = cls.typeParameters[i];
+        DartType arg = substitute(args[i], substitution);
+        substitution[parameter] = arg;
+        int index = translator.typeParameterIndex[parameter]!;
+        Constant typeArgConstant = TypeLiteralConstant(arg);
+        subConstants[index] = typeArgConstant;
+        ensureConstant(typeArgConstant);
+      }
+      Supertype? supertype = cls.supertype;
+      if (supertype == null) break;
+      cls = supertype.classNode;
+      args = supertype.typeArguments;
+    }
+
+    return createConstant(constant, type, (function, b) {
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      for (int i = baseFieldCount; i < fieldCount; i++) {
+        Constant subConstant = subConstants[i]!;
+        constants.instantiateConstant(
+            function, b, subConstant, info.struct.fields[i].type.unpacked);
+      }
+      translator.struct_new(b, info);
+    });
+  }
+
+  @override
+  ConstantInfo? visitListConstant(ListConstant constant) {
+    Constant typeArgConstant = TypeLiteralConstant(constant.typeArgument);
+    ensureConstant(typeArgConstant);
+    for (Constant subConstant in constant.entries) {
+      ensureConstant(subConstant);
+    }
+
+    ClassInfo info = translator.classInfo[translator.immutableListClass]!;
+    translator.functions.allocateClass(info.classId);
+    w.RefType type = info.nonNullableType;
+    return createConstant(constant, type, (function, b) {
+      w.RefType refType = info.struct.fields.last.type.unpacked as w.RefType;
+      w.ArrayType arrayType = refType.heapType as w.ArrayType;
+      w.ValueType elementType = arrayType.elementType.type.unpacked;
+      int length = constant.entries.length;
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      constants.instantiateConstant(
+          function, b, typeArgConstant, constants.typeInfo.nullableType);
+      b.i64_const(length);
+      if (lazyConstants) {
+        // Allocate array and set each entry to the corresponding sub-constant.
+        w.Local arrayLocal = function!.addLocal(
+            refType.withNullability(!translator.options.localNullability));
+        b.i32_const(length);
+        translator.array_new_default(b, arrayType);
+        b.local_set(arrayLocal);
+        for (int i = 0; i < length; i++) {
+          b.local_get(arrayLocal);
+          b.i32_const(i);
+          constants.instantiateConstant(
+              function, b, constant.entries[i], elementType);
+          b.array_set(arrayType);
+        }
+        b.local_get(arrayLocal);
+        if (arrayLocal.type.nullable) {
+          b.ref_as_non_null();
+        }
+      } else {
+        // Push all sub-constants on the stack and initialize array from them.
+        for (int i = 0; i < length; i++) {
+          constants.instantiateConstant(
+              function, b, constant.entries[i], elementType);
+        }
+        translator.array_init(b, arrayType, length);
+      }
+      translator.struct_new(b, info);
+    });
+  }
+
+  @override
+  ConstantInfo? visitStaticTearOffConstant(StaticTearOffConstant constant) {
+    w.DefinedFunction closureFunction =
+        translator.getTearOffFunction(constant.targetReference.asProcedure);
+    int parameterCount = closureFunction.type.inputs.length - 1;
+    w.StructType struct = translator.closureStructType(parameterCount);
+    w.RefType type = w.RefType.def(struct, nullable: false);
+    return createConstant(constant, type, (function, b) {
+      ClassInfo info = translator.classInfo[translator.functionClass]!;
+      translator.functions.allocateClass(info.classId);
+
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.global_get(translator.globals.dummyGlobal); // Dummy context
+      if (lazyConstants) {
+        w.DefinedGlobal global = translator.makeFunctionRef(closureFunction);
+        b.global_get(global);
+      } else {
+        b.ref_func(closureFunction);
+      }
+      translator.struct_new(b, parameterCount);
+    });
+  }
+
+  @override
+  ConstantInfo? visitTypeLiteralConstant(TypeLiteralConstant constant) {
+    DartType cType = constant.type;
+    assert(cType is! TypeParameterType);
+    DartType type = cType is DynamicType ||
+            cType is VoidType ||
+            cType is NeverType ||
+            cType is NullType
+        ? translator.coreTypes.objectRawType(Nullability.nullable)
+        : cType is FunctionType
+            ? InterfaceType(translator.functionClass, cType.declaredNullability)
+            : cType;
+    if (type is! InterfaceType) throw "Not implemented: $constant";
+
+    ListConstant typeArgs = ListConstant(
+        InterfaceType(translator.typeClass, Nullability.nonNullable),
+        type.typeArguments.map((t) => TypeLiteralConstant(t)).toList());
+    ensureConstant(typeArgs);
+
+    ClassInfo info = constants.typeInfo;
+    translator.functions.allocateClass(info.classId);
+    return createConstant(constant, info.nonNullableType, (function, b) {
+      ClassInfo typeInfo = translator.classInfo[type.classNode]!;
+      w.ValueType typeListExpectedType = info.struct.fields[3].type.unpacked;
+
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.i64_const(typeInfo.classId);
+      constants.instantiateConstant(
+          function, b, typeArgs, typeListExpectedType);
+      translator.struct_new(b, info);
+    });
+  }
+}
diff --git a/pkg/dart2wasm/lib/constants_backend.dart b/pkg/dart2wasm/lib/constants_backend.dart
new file mode 100644
index 0000000..6871599
--- /dev/null
+++ b/pkg/dart2wasm/lib/constants_backend.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2022, 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:kernel/ast.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/core_types.dart';
+
+class WasmConstantsBackend extends ConstantsBackend {
+  final Class immutableMapClass;
+  final Class unmodifiableSetClass;
+  final Field unmodifiableSetMap;
+
+  WasmConstantsBackend._(this.immutableMapClass, this.unmodifiableSetMap,
+      this.unmodifiableSetClass);
+
+  factory WasmConstantsBackend(CoreTypes coreTypes) {
+    final Library coreLibrary = coreTypes.coreLibrary;
+    final Class immutableMapClass = coreLibrary.classes
+        .firstWhere((Class klass) => klass.name == '_ImmutableMap');
+    Field unmodifiableSetMap =
+        coreTypes.index.getField('dart:collection', '_UnmodifiableSet', '_map');
+
+    return new WasmConstantsBackend._(immutableMapClass, unmodifiableSetMap,
+        unmodifiableSetMap.enclosingClass!);
+  }
+
+  @override
+  Constant lowerMapConstant(MapConstant constant) {
+    // The _ImmutableMap class is implemented via one field pointing to a list
+    // of key/value pairs -- see runtime/lib/immutable_map.dart!
+    final List<Constant> kvListPairs =
+        new List<Constant>.generate(2 * constant.entries.length, (int i) {
+      final int index = i ~/ 2;
+      final ConstantMapEntry entry = constant.entries[index];
+      return i % 2 == 0 ? entry.key : entry.value;
+    });
+    // This is a bit fishy, since we merge the key and the value type by
+    // putting both into the same list.
+    final ListConstant kvListConstant =
+        new ListConstant(const DynamicType(), kvListPairs);
+    assert(immutableMapClass.fields.length == 1);
+    final Field kvPairListField = immutableMapClass.fields[0];
+    return new InstanceConstant(immutableMapClass.reference, <DartType>[
+      constant.keyType,
+      constant.valueType,
+    ], <Reference, Constant>{
+      // We use getterReference as we refer to the field itself.
+      kvPairListField.getterReference: kvListConstant,
+    });
+  }
+
+  @override
+  bool isLoweredMapConstant(Constant constant) {
+    return constant is InstanceConstant &&
+        constant.classNode == immutableMapClass;
+  }
+
+  @override
+  void forEachLoweredMapConstantEntry(
+      Constant constant, void Function(Constant key, Constant value) f) {
+    assert(isLoweredMapConstant(constant));
+    final InstanceConstant instance = constant as InstanceConstant;
+    assert(immutableMapClass.fields.length == 1);
+    final Field kvPairListField = immutableMapClass.fields[0];
+    final ListConstant kvListConstant =
+        instance.fieldValues[kvPairListField.getterReference] as ListConstant;
+    assert(kvListConstant.entries.length % 2 == 0);
+    for (int index = 0; index < kvListConstant.entries.length; index += 2) {
+      f(kvListConstant.entries[index], kvListConstant.entries[index + 1]);
+    }
+  }
+
+  @override
+  Constant lowerSetConstant(SetConstant constant) {
+    final DartType elementType = constant.typeArgument;
+    final List<Constant> entries = constant.entries;
+    final List<ConstantMapEntry> mapEntries =
+        new List<ConstantMapEntry>.generate(entries.length, (int index) {
+      return new ConstantMapEntry(entries[index], new NullConstant());
+    });
+    Constant map = lowerMapConstant(
+        new MapConstant(elementType, const NullType(), mapEntries));
+    return new InstanceConstant(unmodifiableSetClass.reference, [elementType],
+        <Reference, Constant>{unmodifiableSetMap.getterReference: map});
+  }
+
+  @override
+  bool isLoweredSetConstant(Constant constant) {
+    if (constant is InstanceConstant &&
+        constant.classNode == unmodifiableSetClass) {
+      InstanceConstant instance = constant;
+      return isLoweredMapConstant(
+          instance.fieldValues[unmodifiableSetMap.getterReference]!);
+    }
+    return false;
+  }
+
+  @override
+  void forEachLoweredSetConstantElement(
+      Constant constant, void Function(Constant element) f) {
+    assert(isLoweredSetConstant(constant));
+    final InstanceConstant instance = constant as InstanceConstant;
+    final Constant mapConstant =
+        instance.fieldValues[unmodifiableSetMap.getterReference]!;
+    forEachLoweredMapConstantEntry(mapConstant, (Constant key, Constant value) {
+      f(key);
+    });
+  }
+}
diff --git a/pkg/dart2wasm/lib/dispatch_table.dart b/pkg/dart2wasm/lib/dispatch_table.dart
new file mode 100644
index 0000000..3c6b024
--- /dev/null
+++ b/pkg/dart2wasm/lib/dispatch_table.dart
@@ -0,0 +1,308 @@
+// Copyright (c) 2022, 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 'dart:math';
+
+import 'package:dart2wasm/class_info.dart';
+import 'package:dart2wasm/param_info.dart';
+import 'package:dart2wasm/reference_extensions.dart';
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+
+import 'package:vm/metadata/procedure_attributes.dart';
+import 'package:vm/metadata/table_selector.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// Information for a dispatch table selector.
+class SelectorInfo {
+  final Translator translator;
+
+  final int id;
+  final int callCount;
+  final bool tornOff;
+  final ParameterInfo paramInfo;
+  int returnCount;
+
+  final Map<int, Reference> targets = {};
+  late final w.FunctionType signature = computeSignature();
+
+  late final List<int> classIds;
+  late final int targetCount;
+  bool forced = false;
+  Reference? singularTarget;
+  int? offset;
+
+  String get name => paramInfo.member.name.text;
+
+  bool get alive => callCount > 0 && targetCount > 1 || forced;
+
+  int get sortWeight => classIds.length * 10 + callCount;
+
+  SelectorInfo(this.translator, this.id, this.callCount, this.tornOff,
+      this.paramInfo, this.returnCount);
+
+  /// Compute the signature for the functions implementing members targeted by
+  /// this selector.
+  ///
+  /// When the selector has multiple targets, the type of each parameter/return
+  /// is the upper bound across all targets, such that all targets have the
+  /// same signature, and the actual representation types of the parameters and
+  /// returns are subtypes (resp. supertypes) of the types in the signature.
+  w.FunctionType computeSignature() {
+    var nameIndex = paramInfo.nameIndex;
+    List<Set<ClassInfo>> inputSets =
+        List.generate(1 + paramInfo.paramCount, (_) => {});
+    List<Set<ClassInfo>> outputSets = List.generate(returnCount, (_) => {});
+    List<bool> inputNullable = List.filled(1 + paramInfo.paramCount, false);
+    List<bool> outputNullable = List.filled(returnCount, false);
+    targets.forEach((id, target) {
+      ClassInfo receiver = translator.classes[id];
+      List<DartType> positional;
+      Map<String, DartType> named;
+      List<DartType> returns;
+      Member member = target.asMember;
+      if (member is Field) {
+        if (target.isImplicitGetter) {
+          positional = const [];
+          named = const {};
+          returns = [member.getterType];
+        } else {
+          positional = [member.setterType];
+          named = const {};
+          returns = const [];
+        }
+      } else {
+        FunctionNode function = member.function!;
+        if (target.isTearOffReference) {
+          positional = const [];
+          named = const {};
+          returns = [function.computeFunctionType(Nullability.nonNullable)];
+        } else {
+          positional = [
+            for (VariableDeclaration param in function.positionalParameters)
+              param.type
+          ];
+          named = {
+            for (VariableDeclaration param in function.namedParameters)
+              param.name!: param.type
+          };
+          returns = function.returnType is VoidType
+              ? const []
+              : [function.returnType];
+        }
+      }
+      assert(returns.length <= outputSets.length);
+      inputSets[0].add(receiver);
+      for (int i = 0; i < positional.length; i++) {
+        DartType type = positional[i];
+        inputSets[1 + i]
+            .add(translator.classInfo[translator.classForType(type)]!);
+        inputNullable[1 + i] |= type.isPotentiallyNullable;
+      }
+      for (String name in named.keys) {
+        int i = nameIndex[name]!;
+        DartType type = named[name]!;
+        inputSets[1 + i]
+            .add(translator.classInfo[translator.classForType(type)]!);
+        inputNullable[1 + i] |= type.isPotentiallyNullable;
+      }
+      for (int i = 0; i < returnCount; i++) {
+        if (i < returns.length) {
+          outputSets[i]
+              .add(translator.classInfo[translator.classForType(returns[i])]!);
+          outputNullable[i] |= returns[i].isPotentiallyNullable;
+        } else {
+          outputNullable[i] = true;
+        }
+      }
+    });
+
+    List<w.ValueType> typeParameters = List.filled(paramInfo.typeParamCount,
+        translator.classInfo[translator.typeClass]!.nullableType);
+    List<w.ValueType> inputs = List.generate(
+        inputSets.length,
+        (i) => translator.typeForInfo(
+            upperBound(inputSets[i]), inputNullable[i]) as w.ValueType);
+    inputs[0] = translator.ensureBoxed(inputs[0]);
+    if (name == '==') {
+      // == can't be called with null
+      inputs[1] = inputs[1].withNullability(false);
+    }
+    List<w.ValueType> outputs = List.generate(
+        outputSets.length,
+        (i) => translator.typeForInfo(
+            upperBound(outputSets[i]), outputNullable[i]) as w.ValueType);
+    return translator.functionType(
+        [inputs[0], ...typeParameters, ...inputs.sublist(1)], outputs);
+  }
+}
+
+// Build dispatch table for member calls.
+class DispatchTable {
+  final Translator translator;
+  final List<TableSelectorInfo> selectorMetadata;
+  final Map<TreeNode, ProcedureAttributesMetadata> procedureAttributeMetadata;
+
+  final Map<int, SelectorInfo> selectorInfo = {};
+  final Map<String, int> dynamicGets = {};
+  late final List<Reference?> table;
+
+  DispatchTable(this.translator)
+      : selectorMetadata =
+            (translator.component.metadata["vm.table-selector.metadata"]
+                    as TableSelectorMetadataRepository)
+                .mapping[translator.component]!
+                .selectors,
+        procedureAttributeMetadata =
+            (translator.component.metadata["vm.procedure-attributes.metadata"]
+                    as ProcedureAttributesMetadataRepository)
+                .mapping;
+
+  SelectorInfo selectorForTarget(Reference target) {
+    Member member = target.asMember;
+    bool isGetter = target.isGetter || target.isTearOffReference;
+    ProcedureAttributesMetadata metadata = procedureAttributeMetadata[member]!;
+    int selectorId = isGetter
+        ? metadata.getterSelectorId
+        : metadata.methodOrSetterSelectorId;
+    ParameterInfo paramInfo = ParameterInfo.fromMember(target);
+    int returnCount = isGetter ||
+            member is Procedure && member.function.returnType is! VoidType
+        ? 1
+        : 0;
+    bool calledDynamically = isGetter && metadata.getterCalledDynamically;
+    if (calledDynamically) {
+      // Merge all same-named getter selectors that are called dynamically.
+      selectorId = dynamicGets.putIfAbsent(member.name.text, () => selectorId);
+    }
+    var selector = selectorInfo.putIfAbsent(
+        selectorId,
+        () => SelectorInfo(
+            translator,
+            selectorId,
+            selectorMetadata[selectorId].callCount,
+            selectorMetadata[selectorId].tornOff,
+            paramInfo,
+            returnCount)
+          ..forced = calledDynamically);
+    selector.paramInfo.merge(paramInfo);
+    selector.returnCount = max(selector.returnCount, returnCount);
+    return selector;
+  }
+
+  SelectorInfo selectorForDynamicName(String name) {
+    return selectorInfo[dynamicGets[name]!]!;
+  }
+
+  void build() {
+    // Collect class/selector combinations
+    List<List<int>> selectorsInClass = [];
+    for (ClassInfo info in translator.classes) {
+      List<int> selectorIds = [];
+      ClassInfo? superInfo = info.superInfo;
+      if (superInfo != null) {
+        int superId = superInfo.classId;
+        selectorIds = List.of(selectorsInClass[superId]);
+        for (int selectorId in selectorIds) {
+          SelectorInfo selector = selectorInfo[selectorId]!;
+          selector.targets[info.classId] = selector.targets[superId]!;
+        }
+      }
+
+      SelectorInfo addMember(Reference reference) {
+        SelectorInfo selector = selectorForTarget(reference);
+        if (reference.asMember.isAbstract) {
+          selector.targets[info.classId] ??= reference;
+        } else {
+          selector.targets[info.classId] = reference;
+        }
+        selectorIds.add(selector.id);
+        return selector;
+      }
+
+      for (Member member
+          in info.cls?.members ?? translator.coreTypes.objectClass.members) {
+        if (member.isInstanceMember) {
+          if (member is Field) {
+            addMember(member.getterReference);
+            if (member.hasSetter) addMember(member.setterReference!);
+          } else if (member is Procedure) {
+            SelectorInfo method = addMember(member.reference);
+            if (method.tornOff) {
+              addMember(member.tearOffReference);
+            }
+          }
+        }
+      }
+      selectorsInClass.add(selectorIds);
+    }
+
+    // Build lists of class IDs and count targets
+    for (SelectorInfo selector in selectorInfo.values) {
+      selector.classIds = selector.targets.keys
+          .where((id) => !(translator.classes[id].cls?.isAbstract ?? true))
+          .toList()
+        ..sort();
+      Set<Reference> targets =
+          selector.targets.values.where((t) => !t.asMember.isAbstract).toSet();
+      selector.targetCount = targets.length;
+      if (targets.length == 1) selector.singularTarget = targets.single;
+    }
+
+    // Assign selector offsets
+    List<SelectorInfo> selectors = selectorInfo.values
+        .where((s) => s.alive)
+        .toList()
+      ..sort((a, b) => b.sortWeight - a.sortWeight);
+    int firstAvailable = 0;
+    table = [];
+    bool first = true;
+    for (SelectorInfo selector in selectors) {
+      int offset = first ? 0 : firstAvailable - selector.classIds.first;
+      first = false;
+      bool fits;
+      do {
+        fits = true;
+        for (int classId in selector.classIds) {
+          int entry = offset + classId;
+          if (entry >= table.length) {
+            // Fits
+            break;
+          }
+          if (table[entry] != null) {
+            fits = false;
+            break;
+          }
+        }
+        if (!fits) offset++;
+      } while (!fits);
+      selector.offset = offset;
+      for (int classId in selector.classIds) {
+        int entry = offset + classId;
+        while (table.length <= entry) table.add(null);
+        assert(table[entry] == null);
+        table[entry] = selector.targets[classId];
+      }
+      while (firstAvailable < table.length && table[firstAvailable] != null) {
+        firstAvailable++;
+      }
+    }
+  }
+
+  void output() {
+    w.Module m = translator.m;
+    w.Table wasmTable = m.addTable(table.length);
+    for (int i = 0; i < table.length; i++) {
+      Reference? target = table[i];
+      if (target != null) {
+        w.BaseFunction? fun = translator.functions.getExistingFunction(target);
+        if (fun != null) {
+          wasmTable.setElement(i, fun);
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/dart2wasm/lib/functions.dart b/pkg/dart2wasm/lib/functions.dart
new file mode 100644
index 0000000..eaee6d1
--- /dev/null
+++ b/pkg/dart2wasm/lib/functions.dart
@@ -0,0 +1,216 @@
+// Copyright (c) 2022, 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:dart2wasm/dispatch_table.dart';
+import 'package:dart2wasm/reference_extensions.dart';
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// This class is responsible for collecting import and export annotations.
+/// It also creates Wasm functions for Dart members and manages the worklist
+/// used to achieve tree shaking.
+class FunctionCollector extends MemberVisitor1<w.FunctionType, Reference> {
+  final Translator translator;
+
+  // Wasm function for each Dart function
+  final Map<Reference, w.BaseFunction> _functions = {};
+  // Names of exported functions
+  final Map<Reference, String> exports = {};
+  // Functions for which code has not yet been generated
+  final List<Reference> worklist = [];
+  // Class IDs for classes that are allocated somewhere in the program
+  final Set<int> _allocatedClasses = {};
+  // For each class ID, which functions should be added to the worklist if an
+  // allocation of that class is encountered
+  final Map<int, List<Reference>> _pendingAllocation = {};
+
+  FunctionCollector(this.translator);
+
+  w.Module get m => translator.m;
+
+  void collectImportsAndExports() {
+    for (Library library in translator.libraries) {
+      for (Procedure procedure in library.procedures) {
+        _importOrExport(procedure);
+      }
+      for (Class cls in library.classes) {
+        for (Procedure procedure in cls.procedures) {
+          _importOrExport(procedure);
+        }
+      }
+    }
+  }
+
+  void _importOrExport(Procedure procedure) {
+    String? importName = translator.getPragma(procedure, "wasm:import");
+    if (importName != null) {
+      int dot = importName.indexOf('.');
+      if (dot != -1) {
+        assert(!procedure.isInstanceMember);
+        String module = importName.substring(0, dot);
+        String name = importName.substring(dot + 1);
+        w.FunctionType ftype = _makeFunctionType(
+            procedure.reference, procedure.function.returnType, null,
+            isImportOrExport: true);
+        _functions[procedure.reference] =
+            m.importFunction(module, name, ftype, "$importName (import)");
+      }
+    }
+    String? exportName =
+        translator.getPragma(procedure, "wasm:export", procedure.name.text);
+    if (exportName != null) {
+      addExport(procedure.reference, exportName);
+    }
+  }
+
+  void addExport(Reference target, String exportName) {
+    exports[target] = exportName;
+  }
+
+  void initialize() {
+    // Add all exports to the worklist
+    for (Reference target in exports.keys) {
+      worklist.add(target);
+      Procedure node = target.asProcedure;
+      assert(!node.isInstanceMember);
+      assert(!node.isGetter);
+      w.FunctionType ftype = _makeFunctionType(
+          target, node.function.returnType, null,
+          isImportOrExport: true);
+      _functions[target] = m.addFunction(ftype, "$node");
+    }
+
+    // Value classes are always implicitly allocated.
+    allocateClass(translator.classInfo[translator.boxedBoolClass]!.classId);
+    allocateClass(translator.classInfo[translator.boxedIntClass]!.classId);
+    allocateClass(translator.classInfo[translator.boxedDoubleClass]!.classId);
+  }
+
+  w.BaseFunction? getExistingFunction(Reference target) {
+    return _functions[target];
+  }
+
+  w.BaseFunction getFunction(Reference target) {
+    return _functions.putIfAbsent(target, () {
+      worklist.add(target);
+      w.FunctionType ftype = target.isTearOffReference
+          ? translator.dispatchTable.selectorForTarget(target).signature
+          : target.asMember.accept1(this, target);
+      return m.addFunction(ftype, "${target.asMember}");
+    });
+  }
+
+  void activateSelector(SelectorInfo selector) {
+    selector.targets.forEach((classId, target) {
+      if (!target.asMember.isAbstract) {
+        if (_allocatedClasses.contains(classId)) {
+          // Class declaring or inheriting member is allocated somewhere.
+          getFunction(target);
+        } else {
+          // Remember the member in case an allocation is encountered later.
+          _pendingAllocation.putIfAbsent(classId, () => []).add(target);
+        }
+      }
+    });
+  }
+
+  void allocateClass(int classId) {
+    if (_allocatedClasses.add(classId)) {
+      // Schedule all members that were pending allocation of this class.
+      for (Reference target in _pendingAllocation[classId] ?? const []) {
+        getFunction(target);
+      }
+    }
+  }
+
+  @override
+  w.FunctionType defaultMember(Member node, Reference target) {
+    throw "No Wasm function for member: $node";
+  }
+
+  @override
+  w.FunctionType visitField(Field node, Reference target) {
+    if (!node.isInstanceMember) {
+      if (target == node.fieldReference) {
+        // Static field initializer function
+        return _makeFunctionType(target, node.type, null);
+      }
+      String kind = target == node.setterReference ? "setter" : "getter";
+      throw "No implicit $kind function for static field: $node";
+    }
+    return translator.dispatchTable.selectorForTarget(target).signature;
+  }
+
+  @override
+  w.FunctionType visitProcedure(Procedure node, Reference target) {
+    assert(!node.isAbstract);
+    return node.isInstanceMember
+        ? translator.dispatchTable.selectorForTarget(node.reference).signature
+        : _makeFunctionType(target, node.function.returnType, null);
+  }
+
+  @override
+  w.FunctionType visitConstructor(Constructor node, Reference target) {
+    return _makeFunctionType(target, VoidType(),
+        translator.classInfo[node.enclosingClass]!.nonNullableType);
+  }
+
+  w.FunctionType _makeFunctionType(
+      Reference target, DartType returnType, w.ValueType? receiverType,
+      {bool isImportOrExport = false}) {
+    Member member = target.asMember;
+    int typeParamCount = 0;
+    Iterable<DartType> params;
+    if (member is Field) {
+      params = [if (target.isImplicitSetter) member.setterType];
+    } else {
+      FunctionNode function = member.function!;
+      typeParamCount = (member is Constructor
+              ? member.enclosingClass.typeParameters
+              : function.typeParameters)
+          .length;
+      List<String> names = [for (var p in function.namedParameters) p.name!]
+        ..sort();
+      Map<String, DartType> nameTypes = {
+        for (var p in function.namedParameters) p.name!: p.type
+      };
+      params = [
+        for (var p in function.positionalParameters) p.type,
+        for (String name in names) nameTypes[name]!
+      ];
+      function.positionalParameters.map((p) => p.type);
+    }
+
+    List<w.ValueType> typeParameters = List.filled(typeParamCount,
+        translator.classInfo[translator.typeClass]!.nullableType);
+
+    // The JS embedder will not accept Wasm struct types as parameter or return
+    // types for functions called from JS. We need to use eqref instead.
+    w.ValueType adjustExternalType(w.ValueType type) {
+      if (isImportOrExport && type.isSubtypeOf(w.RefType.eq())) {
+        return w.RefType.eq();
+      }
+      return type;
+    }
+
+    List<w.ValueType> inputs = [];
+    if (receiverType != null) {
+      inputs.add(adjustExternalType(receiverType));
+    }
+    inputs.addAll(typeParameters.map(adjustExternalType));
+    inputs.addAll(
+        params.map((t) => adjustExternalType(translator.translateType(t))));
+
+    List<w.ValueType> outputs = returnType is VoidType ||
+            returnType is NeverType ||
+            returnType is NullType
+        ? const []
+        : [adjustExternalType(translator.translateType(returnType))];
+
+    return translator.functionType(inputs, outputs);
+  }
+}
diff --git a/pkg/dart2wasm/lib/globals.dart b/pkg/dart2wasm/lib/globals.dart
new file mode 100644
index 0000000..c72aeb1
--- /dev/null
+++ b/pkg/dart2wasm/lib/globals.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2022, 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:kernel/ast.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+import 'package:dart2wasm/translator.dart';
+
+/// Handles lazy initialization of static fields.
+class Globals {
+  final Translator translator;
+
+  final Map<Field, w.Global> globals = {};
+  final Map<Field, w.BaseFunction> globalInitializers = {};
+  final Map<Field, w.Global> globalInitializedFlag = {};
+  final Map<w.HeapType, w.DefinedGlobal> dummyValues = {};
+  late final w.DefinedGlobal dummyGlobal;
+
+  Globals(this.translator) {
+    _initDummyValues();
+  }
+
+  void _initDummyValues() {
+    // Create dummy struct for anyref/eqref/dataref/context dummy values
+    w.StructType structType = translator.structType("#Dummy");
+    w.RefType type = w.RefType.def(structType, nullable: false);
+    dummyGlobal = translator.m.addGlobal(w.GlobalType(type, mutable: false));
+    w.Instructions ib = dummyGlobal.initializer;
+    translator.struct_new(ib, structType);
+    ib.end();
+    dummyValues[w.HeapType.any] = dummyGlobal;
+    dummyValues[w.HeapType.eq] = dummyGlobal;
+    dummyValues[w.HeapType.data] = dummyGlobal;
+  }
+
+  w.Global? prepareDummyValue(w.ValueType type) {
+    if (type is w.RefType && !type.nullable) {
+      w.HeapType heapType = type.heapType;
+      w.DefinedGlobal? global = dummyValues[heapType];
+      if (global != null) return global;
+      if (heapType is w.DefType) {
+        if (heapType is w.StructType) {
+          for (w.FieldType field in heapType.fields) {
+            prepareDummyValue(field.type.unpacked);
+          }
+          global = translator.m.addGlobal(w.GlobalType(type, mutable: false));
+          w.Instructions ib = global.initializer;
+          for (w.FieldType field in heapType.fields) {
+            instantiateDummyValue(ib, field.type.unpacked);
+          }
+          translator.struct_new(ib, heapType);
+          ib.end();
+        } else if (heapType is w.ArrayType) {
+          global = translator.m.addGlobal(w.GlobalType(type, mutable: false));
+          w.Instructions ib = global.initializer;
+          translator.array_init(ib, heapType, 0);
+          ib.end();
+        } else if (heapType is w.FunctionType) {
+          w.DefinedFunction function =
+              translator.m.addFunction(heapType, "#dummy function $heapType");
+          w.Instructions b = function.body;
+          b.unreachable();
+          b.end();
+          global = translator.m.addGlobal(w.GlobalType(type, mutable: false));
+          w.Instructions ib = global.initializer;
+          ib.ref_func(function);
+          ib.end();
+        }
+        dummyValues[heapType] = global!;
+      }
+      return global;
+    }
+
+    return null;
+  }
+
+  void instantiateDummyValue(w.Instructions b, w.ValueType type) {
+    w.Global? global = prepareDummyValue(type);
+    switch (type) {
+      case w.NumType.i32:
+        b.i32_const(0);
+        break;
+      case w.NumType.i64:
+        b.i64_const(0);
+        break;
+      case w.NumType.f32:
+        b.f32_const(0);
+        break;
+      case w.NumType.f64:
+        b.f64_const(0);
+        break;
+      default:
+        if (type is w.RefType) {
+          w.HeapType heapType = type.heapType;
+          if (type.nullable) {
+            b.ref_null(heapType);
+          } else {
+            b.global_get(global!);
+          }
+        } else {
+          throw "Unsupported global type ${type} ($type)";
+        }
+        break;
+    }
+  }
+
+  Constant? _getConstantInitializer(Field variable) {
+    Expression? init = variable.initializer;
+    if (init == null || init is NullLiteral) return NullConstant();
+    if (init is IntLiteral) return IntConstant(init.value);
+    if (init is DoubleLiteral) return DoubleConstant(init.value);
+    if (init is BoolLiteral) return BoolConstant(init.value);
+    if (translator.options.lazyConstants) return null;
+    if (init is StringLiteral) return StringConstant(init.value);
+    if (init is ConstantExpression) return init.constant;
+    return null;
+  }
+
+  /// Return (and if needed create) the Wasm global corresponding to a static
+  /// field.
+  w.Global getGlobal(Field variable) {
+    assert(!variable.isLate);
+    return globals.putIfAbsent(variable, () {
+      w.ValueType type = translator.translateType(variable.type);
+      Constant? init = _getConstantInitializer(variable);
+      if (init != null) {
+        // Initialized to a constant
+        translator.constants.ensureConstant(init);
+        w.DefinedGlobal global = translator.m
+            .addGlobal(w.GlobalType(type, mutable: !variable.isFinal));
+        translator.constants
+            .instantiateConstant(null, global.initializer, init, type);
+        global.initializer.end();
+        return global;
+      } else {
+        if (type is w.RefType && !type.nullable) {
+          // Null signals uninitialized
+          type = type.withNullability(true);
+        } else {
+          // Explicit initialization flag
+          w.DefinedGlobal flag =
+              translator.m.addGlobal(w.GlobalType(w.NumType.i32));
+          flag.initializer.i32_const(0);
+          flag.initializer.end();
+          globalInitializedFlag[variable] = flag;
+        }
+
+        w.DefinedGlobal global = translator.m.addGlobal(w.GlobalType(type));
+        instantiateDummyValue(global.initializer, type);
+        global.initializer.end();
+
+        globalInitializers[variable] =
+            translator.functions.getFunction(variable.fieldReference);
+        return global;
+      }
+    });
+  }
+
+  /// Return the Wasm global containing the flag indicating whether this static
+  /// field has been initialized, if such a flag global is needed.
+  ///
+  /// Note that [getGlobal] must have been called for the field beforehand.
+  w.Global? getGlobalInitializedFlag(Field variable) {
+    return globalInitializedFlag[variable];
+  }
+
+  /// Emit code to read a static field.
+  w.ValueType readGlobal(w.Instructions b, Field variable) {
+    w.Global global = getGlobal(variable);
+    w.BaseFunction? initFunction = globalInitializers[variable];
+    if (initFunction == null) {
+      // Statically initialized
+      b.global_get(global);
+      return global.type.type;
+    }
+    w.Global? flag = globalInitializedFlag[variable];
+    if (flag != null) {
+      // Explicit initialization flag
+      assert(global.type.type == initFunction.type.outputs.single);
+      b.global_get(flag);
+      b.if_(const [], [global.type.type]);
+      b.global_get(global);
+      b.else_();
+      b.call(initFunction);
+      b.end();
+    } else {
+      // Null signals uninitialized
+      w.Label block = b.block(const [], [initFunction.type.outputs.single]);
+      b.global_get(global);
+      b.br_on_non_null(block);
+      b.call(initFunction);
+      b.end();
+    }
+    return initFunction.type.outputs.single;
+  }
+}
diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart
new file mode 100644
index 0000000..d94cd8c
--- /dev/null
+++ b/pkg/dart2wasm/lib/intrinsics.dart
@@ -0,0 +1,931 @@
+// Copyright (c) 2022, 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:dart2wasm/class_info.dart';
+import 'package:dart2wasm/code_generator.dart';
+import 'package:dart2wasm/translator.dart';
+
+import 'package:kernel/ast.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// Specialized code generation for external members.
+///
+/// The code is generated either inlined at the call site, or as the body of the
+/// member in [generateMemberIntrinsic].
+class Intrinsifier {
+  final CodeGenerator codeGen;
+  static const w.ValueType boolType = w.NumType.i32;
+  static const w.ValueType intType = w.NumType.i64;
+  static const w.ValueType doubleType = w.NumType.f64;
+
+  static final Map<w.ValueType, Map<w.ValueType, Map<String, CodeGenCallback>>>
+      binaryOperatorMap = {
+    intType: {
+      intType: {
+        '+': (b) => b.i64_add(),
+        '-': (b) => b.i64_sub(),
+        '*': (b) => b.i64_mul(),
+        '~/': (b) => b.i64_div_s(),
+        '&': (b) => b.i64_and(),
+        '|': (b) => b.i64_or(),
+        '^': (b) => b.i64_xor(),
+        '<<': (b) => b.i64_shl(),
+        '>>': (b) => b.i64_shr_s(),
+        '>>>': (b) => b.i64_shr_u(),
+        '<': (b) => b.i64_lt_s(),
+        '<=': (b) => b.i64_le_s(),
+        '>': (b) => b.i64_gt_s(),
+        '>=': (b) => b.i64_ge_s(),
+      }
+    },
+    doubleType: {
+      doubleType: {
+        '+': (b) => b.f64_add(),
+        '-': (b) => b.f64_sub(),
+        '*': (b) => b.f64_mul(),
+        '/': (b) => b.f64_div(),
+        '<': (b) => b.f64_lt(),
+        '<=': (b) => b.f64_le(),
+        '>': (b) => b.f64_gt(),
+        '>=': (b) => b.f64_ge(),
+      }
+    },
+  };
+  static final Map<w.ValueType, Map<String, CodeGenCallback>> unaryOperatorMap =
+      {
+    intType: {
+      'unary-': (b) {
+        b.i64_const(-1);
+        b.i64_mul();
+      },
+      '~': (b) {
+        b.i64_const(-1);
+        b.i64_xor();
+      },
+      'toDouble': (b) {
+        b.f64_convert_i64_s();
+      },
+    },
+    doubleType: {
+      'unary-': (b) {
+        b.f64_neg();
+      },
+      'toInt': (b) {
+        b.i64_trunc_sat_f64_s();
+      },
+      'roundToDouble': (b) {
+        b.f64_nearest();
+      },
+      'floorToDouble': (b) {
+        b.f64_floor();
+      },
+      'ceilToDouble': (b) {
+        b.f64_ceil();
+      },
+      'truncateToDouble': (b) {
+        b.f64_trunc();
+      },
+    },
+  };
+  static final Map<String, w.ValueType> unaryResultMap = {
+    'toDouble': w.NumType.f64,
+    'toInt': w.NumType.i64,
+    'roundToDouble': w.NumType.f64,
+    'floorToDouble': w.NumType.f64,
+    'ceilToDouble': w.NumType.f64,
+    'truncateToDouble': w.NumType.f64,
+  };
+
+  Translator get translator => codeGen.translator;
+  w.Instructions get b => codeGen.b;
+
+  DartType dartTypeOf(Expression exp) => codeGen.dartTypeOf(exp);
+
+  w.ValueType typeOfExp(Expression exp) {
+    return translator.translateType(dartTypeOf(exp));
+  }
+
+  static bool isComparison(String op) =>
+      op == '<' || op == '<=' || op == '>' || op == '>=';
+
+  Intrinsifier(this.codeGen);
+
+  w.ValueType? generateInstanceGetterIntrinsic(InstanceGet node) {
+    DartType receiverType = dartTypeOf(node.receiver);
+    String name = node.name.text;
+
+    // _WasmArray.length
+    if (node.interfaceTarget.enclosingClass == translator.wasmArrayBaseClass) {
+      assert(name == 'length');
+      DartType elementType =
+          (receiverType as InterfaceType).typeArguments.single;
+      w.ArrayType arrayType = translator.arrayTypeForDartType(elementType);
+      Expression array = node.receiver;
+      codeGen.wrap(array, w.RefType.def(arrayType, nullable: true));
+      b.array_len(arrayType);
+      b.i64_extend_i32_u();
+      return w.NumType.i64;
+    }
+
+    // int.bitlength
+    if (node.interfaceTarget.enclosingClass == translator.coreTypes.intClass &&
+        name == 'bitLength') {
+      w.Local temp = codeGen.function.addLocal(w.NumType.i64);
+      b.i64_const(64);
+      codeGen.wrap(node.receiver, w.NumType.i64);
+      b.local_tee(temp);
+      b.local_get(temp);
+      b.i64_const(63);
+      b.i64_shr_s();
+      b.i64_xor();
+      b.i64_clz();
+      b.i64_sub();
+      return w.NumType.i64;
+    }
+
+    return null;
+  }
+
+  w.ValueType? generateInstanceIntrinsic(InstanceInvocation node) {
+    Expression receiver = node.receiver;
+    DartType receiverType = dartTypeOf(receiver);
+    String name = node.name.text;
+    Procedure target = node.interfaceTarget;
+
+    // _TypedListBase._setRange
+    if (target.enclosingClass == translator.typedListBaseClass &&
+        name == "_setRange") {
+      // Always fall back to alternative implementation.
+      b.i32_const(0);
+      return w.NumType.i32;
+    }
+
+    // _TypedList._(get|set)(Int|Uint|Float)(8|16|32|64)
+    if (node.interfaceTarget.enclosingClass == translator.typedListClass) {
+      Match? match = RegExp("^_(get|set)(Int|Uint|Float)(8|16|32|64)\$")
+          .matchAsPrefix(name);
+      if (match != null) {
+        bool setter = match.group(1) == "set";
+        bool signed = match.group(2) == "Int";
+        bool float = match.group(2) == "Float";
+        int bytes = int.parse(match.group(3)!) ~/ 8;
+        bool wide = bytes == 8;
+
+        ClassInfo typedListInfo =
+            translator.classInfo[translator.typedListClass]!;
+        w.RefType arrayType = typedListInfo.struct
+            .fields[FieldIndex.typedListArray].type.unpacked as w.RefType;
+        w.ArrayType arrayHeapType = arrayType.heapType as w.ArrayType;
+        w.ValueType valueType = float ? w.NumType.f64 : w.NumType.i64;
+        w.ValueType intType = wide ? w.NumType.i64 : w.NumType.i32;
+
+        // Prepare array and offset
+        w.Local array = codeGen.addLocal(arrayType);
+        w.Local offset = codeGen.addLocal(w.NumType.i32);
+        codeGen.wrap(receiver, typedListInfo.nullableType);
+        b.struct_get(typedListInfo.struct, FieldIndex.typedListArray);
+        b.local_set(array);
+        codeGen.wrap(node.arguments.positional[0], w.NumType.i64);
+        b.i32_wrap_i64();
+        b.local_set(offset);
+
+        if (setter) {
+          // Setter
+          w.Local value = codeGen.addLocal(intType);
+          codeGen.wrap(node.arguments.positional[1], valueType);
+          if (wide) {
+            if (float) {
+              b.i64_reinterpret_f64();
+            }
+          } else {
+            if (float) {
+              b.f32_demote_f64();
+              b.i32_reinterpret_f32();
+            } else {
+              b.i32_wrap_i64();
+            }
+          }
+          b.local_set(value);
+
+          for (int i = 0; i < bytes; i++) {
+            b.local_get(array);
+            b.local_get(offset);
+            if (i > 0) {
+              b.i32_const(i);
+              b.i32_add();
+            }
+            b.local_get(value);
+            if (i > 0) {
+              if (wide) {
+                b.i64_const(i * 8);
+                b.i64_shr_u();
+              } else {
+                b.i32_const(i * 8);
+                b.i32_shr_u();
+              }
+            }
+            if (wide) {
+              b.i32_wrap_i64();
+            }
+            b.array_set(arrayHeapType);
+          }
+          return translator.voidMarker;
+        } else {
+          // Getter
+          for (int i = 0; i < bytes; i++) {
+            b.local_get(array);
+            b.local_get(offset);
+            if (i > 0) {
+              b.i32_const(i);
+              b.i32_add();
+            }
+            if (signed && i == bytes - 1) {
+              b.array_get_s(arrayHeapType);
+            } else {
+              b.array_get_u(arrayHeapType);
+            }
+            if (wide) {
+              if (signed) {
+                b.i64_extend_i32_s();
+              } else {
+                b.i64_extend_i32_u();
+              }
+            }
+            if (i > 0) {
+              if (wide) {
+                b.i64_const(i * 8);
+                b.i64_shl();
+                b.i64_or();
+              } else {
+                b.i32_const(i * 8);
+                b.i32_shl();
+                b.i32_or();
+              }
+            }
+          }
+
+          if (wide) {
+            if (float) {
+              b.f64_reinterpret_i64();
+            }
+          } else {
+            if (float) {
+              b.f32_reinterpret_i32();
+              b.f64_promote_f32();
+            } else {
+              if (signed) {
+                b.i64_extend_i32_s();
+              } else {
+                b.i64_extend_i32_u();
+              }
+            }
+          }
+          return valueType;
+        }
+      }
+    }
+
+    // WasmIntArray.(readSigned|readUnsigned|write)
+    // WasmFloatArray.(read|write)
+    // WasmObjectArray.(read|write)
+    if (node.interfaceTarget.enclosingClass?.superclass ==
+        translator.wasmArrayBaseClass) {
+      DartType elementType =
+          (receiverType as InterfaceType).typeArguments.single;
+      w.ArrayType arrayType = translator.arrayTypeForDartType(elementType);
+      w.StorageType wasmType = arrayType.elementType.type;
+      bool innerExtend =
+          wasmType == w.PackedType.i8 || wasmType == w.PackedType.i16;
+      bool outerExtend =
+          wasmType.unpacked == w.NumType.i32 || wasmType == w.NumType.f32;
+      switch (name) {
+        case 'read':
+        case 'readSigned':
+        case 'readUnsigned':
+          bool unsigned = name == 'readUnsigned';
+          Expression array = receiver;
+          Expression index = node.arguments.positional.single;
+          codeGen.wrap(array, w.RefType.def(arrayType, nullable: true));
+          codeGen.wrap(index, w.NumType.i64);
+          b.i32_wrap_i64();
+          if (innerExtend) {
+            if (unsigned) {
+              b.array_get_u(arrayType);
+            } else {
+              b.array_get_s(arrayType);
+            }
+          } else {
+            b.array_get(arrayType);
+          }
+          if (outerExtend) {
+            if (wasmType == w.NumType.f32) {
+              b.f64_promote_f32();
+              return w.NumType.f64;
+            } else {
+              if (unsigned) {
+                b.i64_extend_i32_u();
+              } else {
+                b.i64_extend_i32_s();
+              }
+              return w.NumType.i64;
+            }
+          }
+          return wasmType.unpacked;
+        case 'write':
+          Expression array = receiver;
+          Expression index = node.arguments.positional[0];
+          Expression value = node.arguments.positional[1];
+          codeGen.wrap(array, w.RefType.def(arrayType, nullable: true));
+          codeGen.wrap(index, w.NumType.i64);
+          b.i32_wrap_i64();
+          codeGen.wrap(value, typeOfExp(value));
+          if (outerExtend) {
+            if (wasmType == w.NumType.f32) {
+              b.f32_demote_f64();
+            } else {
+              b.i32_wrap_i64();
+            }
+          }
+          b.array_set(arrayType);
+          return codeGen.voidMarker;
+        default:
+          throw "Unsupported array method: $name";
+      }
+    }
+
+    // List.[] on list constants
+    if (receiver is ConstantExpression &&
+        receiver.constant is ListConstant &&
+        name == '[]') {
+      ClassInfo info = translator.classInfo[translator.listBaseClass]!;
+      w.RefType listType = info.nullableType;
+      Field arrayField = translator.listBaseClass.fields
+          .firstWhere((f) => f.name.text == '_data');
+      int arrayFieldIndex = translator.fieldIndex[arrayField]!;
+      w.ArrayType arrayType =
+          (info.struct.fields[arrayFieldIndex].type as w.RefType).heapType
+              as w.ArrayType;
+      codeGen.wrap(receiver, listType);
+      b.struct_get(info.struct, arrayFieldIndex);
+      codeGen.wrap(node.arguments.positional.single, w.NumType.i64);
+      b.i32_wrap_i64();
+      b.array_get(arrayType);
+      return translator.topInfo.nullableType;
+    }
+
+    if (node.arguments.positional.length == 1) {
+      // Binary operator
+      Expression left = node.receiver;
+      Expression right = node.arguments.positional.single;
+      DartType argType = dartTypeOf(right);
+      if (argType is VoidType) return null;
+      w.ValueType leftType = translator.translateType(receiverType);
+      w.ValueType rightType = translator.translateType(argType);
+      var code = binaryOperatorMap[leftType]?[rightType]?[name];
+      if (code != null) {
+        w.ValueType outType = isComparison(name) ? w.NumType.i32 : leftType;
+        codeGen.wrap(left, leftType);
+        codeGen.wrap(right, rightType);
+        code(b);
+        return outType;
+      }
+    } else if (node.arguments.positional.length == 0) {
+      // Unary operator
+      Expression operand = node.receiver;
+      w.ValueType opType = translator.translateType(receiverType);
+      var code = unaryOperatorMap[opType]?[name];
+      if (code != null) {
+        codeGen.wrap(operand, opType);
+        code(b);
+        return unaryResultMap[name] ?? opType;
+      }
+    }
+
+    return null;
+  }
+
+  w.ValueType? generateEqualsIntrinsic(EqualsCall node) {
+    w.ValueType leftType = typeOfExp(node.left);
+    w.ValueType rightType = typeOfExp(node.right);
+
+    if (leftType == boolType && rightType == boolType) {
+      codeGen.wrap(node.left, w.NumType.i32);
+      codeGen.wrap(node.right, w.NumType.i32);
+      b.i32_eq();
+      return w.NumType.i32;
+    }
+
+    if (leftType == intType && rightType == intType) {
+      codeGen.wrap(node.left, w.NumType.i64);
+      codeGen.wrap(node.right, w.NumType.i64);
+      b.i64_eq();
+      return w.NumType.i32;
+    }
+
+    if (leftType == doubleType && rightType == doubleType) {
+      codeGen.wrap(node.left, w.NumType.f64);
+      codeGen.wrap(node.right, w.NumType.f64);
+      b.f64_eq();
+      return w.NumType.i32;
+    }
+
+    return null;
+  }
+
+  w.ValueType? generateStaticGetterIntrinsic(StaticGet node) {
+    Member target = node.target;
+
+    // ClassID getters
+    String? className = translator.getPragma(target, "wasm:class-id");
+    if (className != null) {
+      List<String> libAndClass = className.split("#");
+      Class cls = translator.libraries
+          .firstWhere((l) => l.name == libAndClass[0])
+          .classes
+          .firstWhere((c) => c.name == libAndClass[1]);
+      int classId = translator.classInfo[cls]!.classId;
+      b.i64_const(classId);
+      return w.NumType.i64;
+    }
+
+    return null;
+  }
+
+  w.ValueType? generateStaticIntrinsic(StaticInvocation node) {
+    String name = node.name.text;
+
+    // dart:core static functions
+    if (node.target.enclosingLibrary == translator.coreTypes.coreLibrary) {
+      switch (name) {
+        case "identical":
+          Expression first = node.arguments.positional[0];
+          Expression second = node.arguments.positional[1];
+          DartType boolType = translator.coreTypes.boolNonNullableRawType;
+          InterfaceType intType = translator.coreTypes.intNonNullableRawType;
+          DartType doubleType = translator.coreTypes.doubleNonNullableRawType;
+          List<DartType> types = [dartTypeOf(first), dartTypeOf(second)];
+          if (types.every((t) => t == intType)) {
+            codeGen.wrap(first, w.NumType.i64);
+            codeGen.wrap(second, w.NumType.i64);
+            b.i64_eq();
+            return w.NumType.i32;
+          }
+          if (types.any((t) =>
+              t is InterfaceType &&
+              t != boolType &&
+              t != doubleType &&
+              !translator.hierarchy
+                  .isSubtypeOf(intType.classNode, t.classNode))) {
+            codeGen.wrap(first, w.RefType.eq(nullable: true));
+            codeGen.wrap(second, w.RefType.eq(nullable: true));
+            b.ref_eq();
+            return w.NumType.i32;
+          }
+          break;
+        case "_getHash":
+          Expression arg = node.arguments.positional[0];
+          w.ValueType objectType = translator.objectInfo.nullableType;
+          codeGen.wrap(arg, objectType);
+          b.struct_get(translator.objectInfo.struct, FieldIndex.identityHash);
+          b.i64_extend_i32_u();
+          return w.NumType.i64;
+        case "_setHash":
+          Expression arg = node.arguments.positional[0];
+          Expression hash = node.arguments.positional[1];
+          w.ValueType objectType = translator.objectInfo.nullableType;
+          codeGen.wrap(arg, objectType);
+          codeGen.wrap(hash, w.NumType.i64);
+          b.i32_wrap_i64();
+          b.struct_set(translator.objectInfo.struct, FieldIndex.identityHash);
+          return codeGen.voidMarker;
+      }
+    }
+
+    // dart:_internal static functions
+    if (node.target.enclosingLibrary.name == "dart._internal") {
+      switch (name) {
+        case "unsafeCast":
+          w.ValueType targetType =
+              translator.translateType(node.arguments.types.single);
+          Expression operand = node.arguments.positional.single;
+          return codeGen.wrap(operand, targetType);
+        case "allocateOneByteString":
+          ClassInfo info = translator.classInfo[translator.oneByteStringClass]!;
+          translator.functions.allocateClass(info.classId);
+          w.ArrayType arrayType =
+              translator.wasmArrayType(w.PackedType.i8, "WasmI8");
+          Expression length = node.arguments.positional[0];
+          b.i32_const(info.classId);
+          b.i32_const(initialIdentityHash);
+          codeGen.wrap(length, w.NumType.i64);
+          b.i32_wrap_i64();
+          translator.array_new_default(b, arrayType);
+          translator.struct_new(b, info);
+          return info.nonNullableType;
+        case "writeIntoOneByteString":
+          ClassInfo info = translator.classInfo[translator.oneByteStringClass]!;
+          w.ArrayType arrayType =
+              translator.wasmArrayType(w.PackedType.i8, "WasmI8");
+          Field arrayField = translator.oneByteStringClass.fields
+              .firstWhere((f) => f.name.text == '_array');
+          int arrayFieldIndex = translator.fieldIndex[arrayField]!;
+          Expression string = node.arguments.positional[0];
+          Expression index = node.arguments.positional[1];
+          Expression codePoint = node.arguments.positional[2];
+          codeGen.wrap(string, info.nonNullableType);
+          b.struct_get(info.struct, arrayFieldIndex);
+          codeGen.wrap(index, w.NumType.i64);
+          b.i32_wrap_i64();
+          codeGen.wrap(codePoint, w.NumType.i64);
+          b.i32_wrap_i64();
+          b.array_set(arrayType);
+          return codeGen.voidMarker;
+        case "allocateTwoByteString":
+          ClassInfo info = translator.classInfo[translator.twoByteStringClass]!;
+          translator.functions.allocateClass(info.classId);
+          w.ArrayType arrayType =
+              translator.wasmArrayType(w.PackedType.i16, "WasmI16");
+          Expression length = node.arguments.positional[0];
+          b.i32_const(info.classId);
+          b.i32_const(initialIdentityHash);
+          codeGen.wrap(length, w.NumType.i64);
+          b.i32_wrap_i64();
+          translator.array_new_default(b, arrayType);
+          translator.struct_new(b, info);
+          return info.nonNullableType;
+        case "writeIntoTwoByteString":
+          ClassInfo info = translator.classInfo[translator.twoByteStringClass]!;
+          w.ArrayType arrayType =
+              translator.wasmArrayType(w.PackedType.i16, "WasmI16");
+          Field arrayField = translator.oneByteStringClass.fields
+              .firstWhere((f) => f.name.text == '_array');
+          int arrayFieldIndex = translator.fieldIndex[arrayField]!;
+          Expression string = node.arguments.positional[0];
+          Expression index = node.arguments.positional[1];
+          Expression codePoint = node.arguments.positional[2];
+          codeGen.wrap(string, info.nonNullableType);
+          b.struct_get(info.struct, arrayFieldIndex);
+          codeGen.wrap(index, w.NumType.i64);
+          b.i32_wrap_i64();
+          codeGen.wrap(codePoint, w.NumType.i64);
+          b.i32_wrap_i64();
+          b.array_set(arrayType);
+          return codeGen.voidMarker;
+        case "floatToIntBits":
+          codeGen.wrap(node.arguments.positional.single, w.NumType.f64);
+          b.f32_demote_f64();
+          b.i32_reinterpret_f32();
+          b.i64_extend_i32_u();
+          return w.NumType.i64;
+        case "intBitsToFloat":
+          codeGen.wrap(node.arguments.positional.single, w.NumType.i64);
+          b.i32_wrap_i64();
+          b.f32_reinterpret_i32();
+          b.f64_promote_f32();
+          return w.NumType.f64;
+        case "doubleToIntBits":
+          codeGen.wrap(node.arguments.positional.single, w.NumType.f64);
+          b.i64_reinterpret_f64();
+          return w.NumType.i64;
+        case "intBitsToDouble":
+          codeGen.wrap(node.arguments.positional.single, w.NumType.i64);
+          b.f64_reinterpret_i64();
+          return w.NumType.f64;
+        case "getID":
+          assert(node.target.enclosingClass?.name == "ClassID");
+          ClassInfo info = translator.topInfo;
+          codeGen.wrap(node.arguments.positional.single, info.nullableType);
+          b.struct_get(info.struct, FieldIndex.classId);
+          b.i64_extend_i32_u();
+          return w.NumType.i64;
+      }
+    }
+
+    // Wasm(Int|Float|Object)Array constructors
+    if (node.target.enclosingClass?.superclass ==
+        translator.wasmArrayBaseClass) {
+      Expression length = node.arguments.positional[0];
+      w.ArrayType arrayType =
+          translator.arrayTypeForDartType(node.arguments.types.single);
+      codeGen.wrap(length, w.NumType.i64);
+      b.i32_wrap_i64();
+      translator.array_new_default(b, arrayType);
+      return w.RefType.def(arrayType, nullable: false);
+    }
+
+    return null;
+  }
+
+  bool generateMemberIntrinsic(Reference target, w.DefinedFunction function,
+      List<w.Local> paramLocals, w.Label? returnLabel) {
+    Member member = target.asMember;
+    if (member is! Procedure) return false;
+    String name = member.name.text;
+    FunctionNode functionNode = member.function;
+
+    // Object.==
+    if (member == translator.coreTypes.objectEquals) {
+      b.local_get(paramLocals[0]);
+      b.local_get(paramLocals[1]);
+      b.ref_eq();
+      return true;
+    }
+
+    // Object.runtimeType
+    if (member.enclosingClass == translator.coreTypes.objectClass &&
+        name == "runtimeType") {
+      w.Local receiver = paramLocals[0];
+      ClassInfo info = translator.classInfo[translator.typeClass]!;
+      translator.functions.allocateClass(info.classId);
+      w.ValueType typeListExpectedType = info.struct.fields[3].type.unpacked;
+
+      b.i32_const(info.classId);
+      b.i32_const(initialIdentityHash);
+      b.local_get(receiver);
+      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+      b.i64_extend_i32_u();
+      // TODO(askesc): Type arguments
+      b.global_get(translator.constants.emptyTypeList);
+      translator.convertType(function,
+          translator.constants.emptyTypeList.type.type, typeListExpectedType);
+      translator.struct_new(b, info);
+
+      return true;
+    }
+
+    // identical
+    if (member == translator.coreTypes.identicalProcedure) {
+      w.Local first = paramLocals[0];
+      w.Local second = paramLocals[1];
+      ClassInfo boolInfo = translator.classInfo[translator.boxedBoolClass]!;
+      ClassInfo intInfo = translator.classInfo[translator.boxedIntClass]!;
+      ClassInfo doubleInfo = translator.classInfo[translator.boxedDoubleClass]!;
+      w.Local cid = function.addLocal(w.NumType.i32);
+      w.Label ref_eq = b.block();
+      b.local_get(first);
+      b.br_on_null(ref_eq);
+      b.struct_get(translator.topInfo.struct, FieldIndex.classId);
+      b.local_tee(cid);
+
+      // Both bool?
+      b.i32_const(boolInfo.classId);
+      b.i32_eq();
+      b.if_();
+      b.local_get(first);
+      translator.ref_cast(b, boolInfo);
+      b.struct_get(boolInfo.struct, FieldIndex.boxValue);
+      w.Label bothBool = b.block(const [], [boolInfo.nullableType]);
+      b.local_get(second);
+      translator.br_on_cast(b, bothBool, boolInfo);
+      b.i32_const(0);
+      b.return_();
+      b.end();
+      b.struct_get(boolInfo.struct, FieldIndex.boxValue);
+      b.i32_eq();
+      b.return_();
+      b.end();
+
+      // Both int?
+      b.local_get(cid);
+      b.i32_const(intInfo.classId);
+      b.i32_eq();
+      b.if_();
+      b.local_get(first);
+      translator.ref_cast(b, intInfo);
+      b.struct_get(intInfo.struct, FieldIndex.boxValue);
+      w.Label bothInt = b.block(const [], [intInfo.nullableType]);
+      b.local_get(second);
+      translator.br_on_cast(b, bothInt, intInfo);
+      b.i32_const(0);
+      b.return_();
+      b.end();
+      b.struct_get(intInfo.struct, FieldIndex.boxValue);
+      b.i64_eq();
+      b.return_();
+      b.end();
+
+      // Both double?
+      b.local_get(cid);
+      b.i32_const(doubleInfo.classId);
+      b.i32_eq();
+      b.if_();
+      b.local_get(first);
+      translator.ref_cast(b, doubleInfo);
+      b.struct_get(doubleInfo.struct, FieldIndex.boxValue);
+      b.i64_reinterpret_f64();
+      w.Label bothDouble = b.block(const [], [doubleInfo.nullableType]);
+      b.local_get(second);
+      translator.br_on_cast(b, bothDouble, doubleInfo);
+      b.i32_const(0);
+      b.return_();
+      b.end();
+      b.struct_get(doubleInfo.struct, FieldIndex.boxValue);
+      b.i64_reinterpret_f64();
+      b.i64_eq();
+      b.return_();
+      b.end();
+
+      // Compare as references
+      b.end();
+      b.local_get(first);
+      b.local_get(second);
+      b.ref_eq();
+
+      return true;
+    }
+
+    // (Int|Uint|Float)(8|16|32|64)(Clamped)?(List|ArrayView) constructors
+    if (member.isExternal &&
+        member.enclosingLibrary.name == "dart.typed_data") {
+      if (member.isFactory) {
+        String className = member.enclosingClass!.name;
+
+        Match? match = RegExp("^(Int|Uint|Float)(8|16|32|64)(Clamped)?List\$")
+            .matchAsPrefix(className);
+        if (match != null) {
+          int shift = int.parse(match.group(2)!).bitLength - 4;
+          Class cls = member.enclosingLibrary.classes
+              .firstWhere((c) => c.name == "_$className");
+          ClassInfo info = translator.classInfo[cls]!;
+          translator.functions.allocateClass(info.classId);
+          w.ArrayType arrayType =
+              translator.wasmArrayType(w.PackedType.i8, "i8");
+
+          w.Local length = paramLocals[0];
+          b.i32_const(info.classId);
+          b.i32_const(initialIdentityHash);
+          b.local_get(length);
+          b.i32_wrap_i64();
+          b.local_get(length);
+          if (shift > 0) {
+            b.i64_const(shift);
+            b.i64_shl();
+          }
+          b.i32_wrap_i64();
+          translator.array_new_default(b, arrayType);
+          translator.struct_new(b, info);
+          return true;
+        }
+
+        match = RegExp("^_(Int|Uint|Float)(8|16|32|64)(Clamped)?ArrayView\$")
+            .matchAsPrefix(className);
+        if (match != null ||
+            member.enclosingClass == translator.byteDataViewClass) {
+          ClassInfo info = translator.classInfo[member.enclosingClass]!;
+          translator.functions.allocateClass(info.classId);
+
+          w.Local buffer = paramLocals[0];
+          w.Local offsetInBytes = paramLocals[1];
+          w.Local length = paramLocals[2];
+          b.i32_const(info.classId);
+          b.i32_const(initialIdentityHash);
+          b.local_get(length);
+          b.i32_wrap_i64();
+          b.local_get(buffer);
+          b.local_get(offsetInBytes);
+          b.i32_wrap_i64();
+          translator.struct_new(b, info);
+          return true;
+        }
+      }
+
+      // _TypedListBase.length
+      // _TypedListView.offsetInBytes
+      // _TypedListView._typedData
+      // _ByteDataView.length
+      // _ByteDataView.offsetInBytes
+      // _ByteDataView._typedData
+      if (member.isGetter) {
+        Class cls = member.enclosingClass!;
+        ClassInfo info = translator.classInfo[cls]!;
+        b.local_get(paramLocals[0]);
+        translator.ref_cast(b, info);
+        switch (name) {
+          case "length":
+            assert(cls == translator.typedListBaseClass ||
+                cls == translator.byteDataViewClass);
+            if (cls == translator.typedListBaseClass) {
+              b.struct_get(info.struct, FieldIndex.typedListBaseLength);
+            } else {
+              b.struct_get(info.struct, FieldIndex.byteDataViewLength);
+            }
+            b.i64_extend_i32_u();
+            return true;
+          case "offsetInBytes":
+            assert(cls == translator.typedListViewClass ||
+                cls == translator.byteDataViewClass);
+            if (cls == translator.typedListViewClass) {
+              b.struct_get(info.struct, FieldIndex.typedListViewOffsetInBytes);
+            } else {
+              b.struct_get(info.struct, FieldIndex.byteDataViewOffsetInBytes);
+            }
+            b.i64_extend_i32_u();
+            return true;
+          case "_typedData":
+            assert(cls == translator.typedListViewClass ||
+                cls == translator.byteDataViewClass);
+            if (cls == translator.typedListViewClass) {
+              b.struct_get(info.struct, FieldIndex.typedListViewTypedData);
+            } else {
+              b.struct_get(info.struct, FieldIndex.byteDataViewTypedData);
+            }
+            return true;
+        }
+        throw "Unrecognized typed data getter: ${cls.name}.$name";
+      }
+    }
+
+    // int members
+    if (member.enclosingClass == translator.boxedIntClass &&
+        member.function.body == null) {
+      String op = member.name.text;
+      if (functionNode.requiredParameterCount == 0) {
+        CodeGenCallback? code = unaryOperatorMap[intType]![op];
+        if (code != null) {
+          w.ValueType resultType = unaryResultMap[op] ?? intType;
+          w.ValueType inputType = function.type.inputs.single;
+          w.ValueType outputType = function.type.outputs.single;
+          b.local_get(function.locals[0]);
+          translator.convertType(function, inputType, intType);
+          code(b);
+          translator.convertType(function, resultType, outputType);
+          return true;
+        }
+      } else if (functionNode.requiredParameterCount == 1) {
+        CodeGenCallback? code = binaryOperatorMap[intType]![intType]![op];
+        if (code != null) {
+          w.ValueType leftType = function.type.inputs[0];
+          w.ValueType rightType = function.type.inputs[1];
+          w.ValueType outputType = function.type.outputs.single;
+          if (rightType == intType) {
+            // int parameter
+            b.local_get(function.locals[0]);
+            translator.convertType(function, leftType, intType);
+            b.local_get(function.locals[1]);
+            code(b);
+            if (!isComparison(op)) {
+              translator.convertType(function, intType, outputType);
+            }
+            return true;
+          }
+          // num parameter
+          ClassInfo intInfo = translator.classInfo[translator.boxedIntClass]!;
+          w.Label intArg = b.block(const [], [intInfo.nonNullableType]);
+          b.local_get(function.locals[1]);
+          translator.br_on_cast(b, intArg, intInfo);
+          // double argument
+          b.drop();
+          b.local_get(function.locals[0]);
+          translator.convertType(function, leftType, intType);
+          b.f64_convert_i64_s();
+          b.local_get(function.locals[1]);
+          translator.convertType(function, rightType, doubleType);
+          // Inline double op
+          CodeGenCallback doubleCode =
+              binaryOperatorMap[doubleType]![doubleType]![op]!;
+          doubleCode(b);
+          if (!isComparison(op)) {
+            translator.convertType(function, doubleType, outputType);
+          }
+          b.return_();
+          b.end();
+          // int argument
+          translator.convertType(function, intInfo.nonNullableType, intType);
+          w.Local rightTemp = function.addLocal(intType);
+          b.local_set(rightTemp);
+          b.local_get(function.locals[0]);
+          translator.convertType(function, leftType, intType);
+          b.local_get(rightTemp);
+          code(b);
+          if (!isComparison(op)) {
+            translator.convertType(function, intType, outputType);
+          }
+          return true;
+        }
+      }
+    }
+
+    // double unary members
+    if (member.enclosingClass == translator.boxedDoubleClass &&
+        member.function.body == null) {
+      String op = member.name.text;
+      if (functionNode.requiredParameterCount == 0) {
+        CodeGenCallback? code = unaryOperatorMap[doubleType]![op];
+        if (code != null) {
+          w.ValueType resultType = unaryResultMap[op] ?? doubleType;
+          w.ValueType inputType = function.type.inputs.single;
+          w.ValueType outputType = function.type.outputs.single;
+          b.local_get(function.locals[0]);
+          translator.convertType(function, inputType, doubleType);
+          code(b);
+          translator.convertType(function, resultType, outputType);
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+}
diff --git a/pkg/dart2wasm/lib/param_info.dart b/pkg/dart2wasm/lib/param_info.dart
new file mode 100644
index 0000000..182af47
--- /dev/null
+++ b/pkg/dart2wasm/lib/param_info.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2022, 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:dart2wasm/reference_extensions.dart';
+
+import 'package:kernel/ast.dart';
+
+/// Information about optional parameters and their default values for a
+/// member or a set of members belonging to the same override group.
+class ParameterInfo {
+  final Member member;
+  int typeParamCount = 0;
+  late final List<Constant?> positional;
+  late final Map<String, Constant?> named;
+
+  // Do not access these until the info is complete.
+  late final List<String> names = named.keys.toList()..sort();
+  late final Map<String, int> nameIndex = {
+    for (int i = 0; i < names.length; i++) names[i]: positional.length + i
+  };
+
+  int get paramCount => positional.length + named.length;
+
+  static Constant? defaultValue(VariableDeclaration param) {
+    Expression? initializer = param.initializer;
+    if (initializer is ConstantExpression) {
+      return initializer.constant;
+    } else if (initializer == null) {
+      return null;
+    } else {
+      throw "Non-constant default value";
+    }
+  }
+
+  ParameterInfo.fromMember(Reference target) : member = target.asMember {
+    FunctionNode? function = member.function;
+    if (target.isTearOffReference) {
+      positional = [];
+      named = {};
+    } else if (function != null) {
+      typeParamCount = (member is Constructor
+              ? member.enclosingClass!.typeParameters
+              : function.typeParameters)
+          .length;
+      positional = List.generate(function.positionalParameters.length, (i) {
+        // A required parameter has no default value.
+        if (i < function.requiredParameterCount) return null;
+        return defaultValue(function.positionalParameters[i]);
+      });
+      named = {
+        for (VariableDeclaration param in function.namedParameters)
+          param.name!: defaultValue(param)
+      };
+    } else {
+      // A setter parameter has no default value.
+      positional = [if (target.isSetter) null];
+      named = {};
+    }
+  }
+
+  void merge(ParameterInfo other) {
+    assert(typeParamCount == other.typeParamCount);
+    for (int i = 0; i < other.positional.length; i++) {
+      if (i >= positional.length) {
+        positional.add(other.positional[i]);
+      } else {
+        if (positional[i] == null) {
+          positional[i] = other.positional[i];
+        } else if (other.positional[i] != null) {
+          if (positional[i] != other.positional[i]) {
+            print("Mismatching default value for parameter $i: "
+                "${member}: ${positional[i]} vs "
+                "${other.member}: ${other.positional[i]}");
+          }
+        }
+      }
+    }
+    for (String name in other.named.keys) {
+      Constant? value = named[name];
+      Constant? otherValue = other.named[name];
+      if (value == null) {
+        named[name] = otherValue;
+      } else if (otherValue != null) {
+        if (value != otherValue) {
+          print("Mismatching default value for parameter '$name': "
+              "${member}: ${value} vs "
+              "${other.member}: ${otherValue}");
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/dart2wasm/lib/reference_extensions.dart b/pkg/dart2wasm/lib/reference_extensions.dart
new file mode 100644
index 0000000..ba9a68c
--- /dev/null
+++ b/pkg/dart2wasm/lib/reference_extensions.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2022, 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:kernel/ast.dart';
+
+// Extend references with flags to more easily identify getters and setters.
+
+extension GetterSetterReference on Reference {
+  bool get isImplicitGetter {
+    Member member = asMember;
+    return member is Field && member.getterReference == this;
+  }
+
+  bool get isImplicitSetter {
+    Member member = asMember;
+    return member is Field && member.setterReference == this;
+  }
+
+  bool get isGetter {
+    Member member = asMember;
+    return member is Procedure && member.isGetter || isImplicitGetter;
+  }
+
+  bool get isSetter {
+    Member member = asMember;
+    return member is Procedure && member.isSetter || isImplicitSetter;
+  }
+}
+
+// Extend procedures with a tearOffReference that refers to the tear-off
+// implementation for that procedure. This enables a Reference to refer to any
+// implementation relating to a member, including its tear-off, which it can't
+// do in plain kernel.
+
+extension TearOffReference on Procedure {
+  // Use an Expando to avoid keeping the procedure alive.
+  static final Expando<Reference> _tearOffReference = Expando();
+
+  Reference get tearOffReference =>
+      _tearOffReference[this] ??= Reference()..node = this;
+}
+
+extension IsTearOffReference on Reference {
+  bool get isTearOffReference {
+    Member member = asMember;
+    return member is Procedure && member.tearOffReference == this;
+  }
+}
+
+extension ReferenceAs on Member {
+  Reference referenceAs({required bool getter, required bool setter}) {
+    Member member = this;
+    return member is Field
+        ? setter
+            ? member.setterReference!
+            : member.getterReference
+        : getter && member is Procedure && member.kind == ProcedureKind.Method
+            ? member.tearOffReference
+            : member.reference;
+  }
+}
diff --git a/pkg/dart2wasm/lib/target.dart b/pkg/dart2wasm/lib/target.dart
new file mode 100644
index 0000000..a7827e1
--- /dev/null
+++ b/pkg/dart2wasm/lib/target.dart
@@ -0,0 +1,191 @@
+// Copyright (c) 2022, 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:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/clone.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/reference_from_index.dart';
+import 'package:kernel/target/changed_structure_notifier.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/transformations/mixin_full_resolution.dart'
+    as transformMixins show transformLibraries;
+
+import 'package:dart2wasm/constants_backend.dart';
+import 'package:dart2wasm/transformers.dart' as wasmTrans;
+
+class WasmTarget extends Target {
+  Class? _growableList;
+  Class? _immutableList;
+  Class? _immutableMap;
+  Class? _unmodifiableSet;
+  Class? _compactLinkedCustomHashMap;
+  Class? _compactLinkedHashSet;
+  Class? _oneByteString;
+  Class? _twoByteString;
+
+  @override
+  late final ConstantsBackend constantsBackend;
+
+  @override
+  String get name => 'wasm';
+
+  @override
+  TargetFlags get flags => TargetFlags(enableNullSafety: true);
+
+  @override
+  List<String> get extraIndexedLibraries => const <String>[
+        "dart:collection",
+        "dart:typed_data",
+      ];
+
+  void _patchHostEndian(CoreTypes coreTypes) {
+    // Fix Endian.host to be a const field equal to Endian.little instead of
+    // a final field. Wasm is a little-endian platform.
+    // Can't use normal patching process for this because CFE does not
+    // support patching fields.
+    // See http://dartbug.com/32836 for the background.
+    final Field host =
+        coreTypes.index.getField('dart:typed_data', 'Endian', 'host');
+    final Field little =
+        coreTypes.index.getField('dart:typed_data', 'Endian', 'little');
+    host.isConst = true;
+    host.initializer = new CloneVisitorNotMembers().clone(little.initializer!)
+      ..parent = host;
+  }
+
+  @override
+  void performPreConstantEvaluationTransformations(
+      Component component,
+      CoreTypes coreTypes,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
+      {void Function(String msg)? logger,
+      ChangedStructureNotifier? changedStructureNotifier}) {
+    constantsBackend = WasmConstantsBackend(coreTypes);
+    _patchHostEndian(coreTypes);
+  }
+
+  @override
+  void performModularTransformationsOnLibraries(
+      Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<Library> libraries,
+      Map<String, String>? environmentDefines,
+      DiagnosticReporter diagnosticReporter,
+      ReferenceFromIndex? referenceFromIndex,
+      {void logger(String msg)?,
+      ChangedStructureNotifier? changedStructureNotifier}) {
+    transformMixins.transformLibraries(
+        this, coreTypes, hierarchy, libraries, referenceFromIndex);
+    logger?.call("Transformed mixin applications");
+
+    wasmTrans.transformLibraries(libraries, coreTypes, hierarchy);
+  }
+
+  @override
+  void performTransformationsOnProcedure(
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      Procedure procedure,
+      Map<String, String>? environmentDefines,
+      {void logger(String msg)?}) {
+    wasmTrans.transformProcedure(procedure, coreTypes, hierarchy);
+  }
+
+  @override
+  Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
+      String name, Arguments arguments, int offset, bool isSuper) {
+    throw "Unsupported: instantiateInvocation";
+  }
+
+  Expression instantiateNoSuchMethodError(CoreTypes coreTypes,
+      Expression receiver, String name, Arguments arguments, int offset,
+      {bool isMethod: false,
+      bool isGetter: false,
+      bool isSetter: false,
+      bool isField: false,
+      bool isLocalVariable: false,
+      bool isDynamic: false,
+      bool isSuper: false,
+      bool isStatic: false,
+      bool isConstructor: false,
+      bool isTopLevel: false}) {
+    throw "Unsupported: instantiateNoSuchMethodError";
+  }
+
+  @override
+  bool get supportsSetLiterals => false;
+
+  @override
+  int get enabledLateLowerings => LateLowering.all;
+
+  @override
+  int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.all;
+
+  @override
+  bool get supportsExplicitGetterCalls => true;
+
+  @override
+  bool get supportsLateLoweringSentinel => false;
+
+  @override
+  bool get useStaticFieldLowering => false;
+
+  @override
+  bool enableNative(Uri uri) => true;
+
+  @override
+  Class concreteListLiteralClass(CoreTypes coreTypes) {
+    return _growableList ??=
+        coreTypes.index.getClass('dart:core', '_GrowableList');
+  }
+
+  @override
+  Class concreteConstListLiteralClass(CoreTypes coreTypes) {
+    return _immutableList ??=
+        coreTypes.index.getClass('dart:core', '_ImmutableList');
+  }
+
+  @override
+  Class concreteMapLiteralClass(CoreTypes coreTypes) {
+    return _compactLinkedCustomHashMap ??= coreTypes.index
+        .getClass('dart:collection', '_CompactLinkedCustomHashMap');
+  }
+
+  @override
+  Class concreteConstMapLiteralClass(CoreTypes coreTypes) {
+    return _immutableMap ??=
+        coreTypes.index.getClass('dart:collection', '_ImmutableMap');
+  }
+
+  @override
+  Class concreteSetLiteralClass(CoreTypes coreTypes) {
+    return _compactLinkedHashSet ??=
+        coreTypes.index.getClass('dart:collection', '_CompactLinkedHashSet');
+  }
+
+  @override
+  Class concreteConstSetLiteralClass(CoreTypes coreTypes) {
+    return _unmodifiableSet ??=
+        coreTypes.index.getClass('dart:collection', '_UnmodifiableSet');
+  }
+
+  @override
+  Class concreteStringLiteralClass(CoreTypes coreTypes, String value) {
+    const int maxLatin1 = 0xff;
+    for (int i = 0; i < value.length; ++i) {
+      if (value.codeUnitAt(i) > maxLatin1) {
+        return _twoByteString ??=
+            coreTypes.index.getClass('dart:core', '_TwoByteString');
+      }
+    }
+    return _oneByteString ??=
+        coreTypes.index.getClass('dart:core', '_OneByteString');
+  }
+
+  @override
+  bool isSupportedPragma(String pragmaName) => pragmaName.startsWith("wasm:");
+}
diff --git a/pkg/dart2wasm/lib/transformers.dart b/pkg/dart2wasm/lib/transformers.dart
new file mode 100644
index 0000000..83793e3
--- /dev/null
+++ b/pkg/dart2wasm/lib/transformers.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2022, 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:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
+
+void transformLibraries(
+    List<Library> libraries, CoreTypes coreTypes, ClassHierarchy hierarchy) {
+  final transformer = _WasmTransformer(coreTypes, hierarchy);
+  libraries.forEach(transformer.visitLibrary);
+}
+
+void transformProcedure(
+    Procedure procedure, CoreTypes coreTypes, ClassHierarchy hierarchy) {
+  final transformer = _WasmTransformer(coreTypes, hierarchy);
+  procedure.accept(transformer);
+}
+
+class _WasmTransformer extends Transformer {
+  final TypeEnvironment env;
+
+  Member? _currentMember;
+  StaticTypeContext? _cachedTypeContext;
+
+  StaticTypeContext get typeContext =>
+      _cachedTypeContext ??= StaticTypeContext(_currentMember!, env);
+
+  _WasmTransformer(CoreTypes coreTypes, ClassHierarchy hierarchy)
+      : env = TypeEnvironment(coreTypes, hierarchy);
+
+  @override
+  defaultMember(Member node) {
+    _currentMember = node;
+    _cachedTypeContext = null;
+
+    final result = super.defaultMember(node);
+
+    _currentMember = null;
+    _cachedTypeContext = null;
+    return result;
+  }
+
+  @override
+  TreeNode visitForInStatement(ForInStatement stmt) {
+    // Transform
+    //
+    //   for ({var/final} T <variable> in <iterable>) { ... }
+    //
+    // Into
+    //
+    //  {
+    //    final Iterator<T> #forIterator = <iterable>.iterator;
+    //    for (; #forIterator.moveNext() ;) {
+    //        {var/final} T variable = #forIterator.current;
+    //        ...
+    //      }
+    //    }
+    //  }
+    final CoreTypes coreTypes = typeContext.typeEnvironment.coreTypes;
+
+    // The CFE might invoke this transformation despite the program having
+    // compile-time errors. So we will not transform this [stmt] if the
+    // `stmt.iterable` is an invalid expression or has an invalid type and
+    // instead eliminate the entire for-in and replace it with a invalid
+    // expression statement.
+    final iterable = stmt.iterable;
+    final iterableType = iterable.getStaticType(typeContext);
+    if (iterableType is InvalidType) {
+      return ExpressionStatement(
+          InvalidExpression('Invalid iterable type in for-in'));
+    }
+
+    final DartType elementType = stmt.getElementType(typeContext);
+    final iteratorType = InterfaceType(
+        coreTypes.iteratorClass, Nullability.nonNullable, [elementType]);
+
+    final iterator = VariableDeclaration("#forIterator",
+        initializer: InstanceGet(
+            InstanceAccessKind.Instance, iterable, Name('iterator'),
+            interfaceTarget: coreTypes.iterableGetIterator,
+            resultType: coreTypes.iterableGetIterator.function.returnType)
+          ..fileOffset = iterable.fileOffset,
+        type: iteratorType)
+      ..fileOffset = iterable.fileOffset;
+
+    final condition = InstanceInvocation(InstanceAccessKind.Instance,
+        VariableGet(iterator), Name('moveNext'), Arguments(const []),
+        interfaceTarget: coreTypes.iteratorMoveNext,
+        functionType: coreTypes.iteratorMoveNext.function
+            .computeFunctionType(Nullability.nonNullable))
+      ..fileOffset = iterable.fileOffset;
+
+    final variable = stmt.variable
+      ..initializer = (InstanceGet(
+          InstanceAccessKind.Instance, VariableGet(iterator), Name('current'),
+          interfaceTarget: coreTypes.iteratorGetCurrent,
+          resultType: coreTypes.iteratorGetCurrent.function.returnType)
+        ..fileOffset = stmt.bodyOffset);
+
+    final Block body = Block([variable, stmt.body]);
+
+    return Block([iterator, ForStatement(const [], condition, const [], body)])
+        .accept<TreeNode>(this);
+  }
+}
diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart
new file mode 100644
index 0000000..7a33ce4
--- /dev/null
+++ b/pkg/dart2wasm/lib/translator.dart
@@ -0,0 +1,819 @@
+// Copyright (c) 2022, 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 'dart:typed_data';
+
+import 'package:dart2wasm/class_info.dart';
+import 'package:dart2wasm/closures.dart';
+import 'package:dart2wasm/code_generator.dart';
+import 'package:dart2wasm/constants.dart';
+import 'package:dart2wasm/dispatch_table.dart';
+import 'package:dart2wasm/functions.dart';
+import 'package:dart2wasm/globals.dart';
+import 'package:dart2wasm/param_info.dart';
+import 'package:dart2wasm/reference_extensions.dart';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart'
+    show ClassHierarchy, ClassHierarchySubtypes, ClosedWorldClassHierarchy;
+import 'package:kernel/core_types.dart';
+import 'package:kernel/src/printer.dart';
+import 'package:kernel/type_environment.dart';
+import 'package:vm/metadata/direct_call.dart';
+
+import 'package:wasm_builder/wasm_builder.dart' as w;
+
+/// Options controlling the translation.
+class TranslatorOptions {
+  bool exportAll = false;
+  bool inlining = false;
+  int inliningLimit = 3;
+  bool lazyConstants = false;
+  bool localNullability = false;
+  bool nameSection = true;
+  bool nominalTypes = false;
+  bool parameterNullability = true;
+  bool polymorphicSpecialization = false;
+  bool printKernel = false;
+  bool printWasm = false;
+  bool runtimeTypes = true;
+  bool stringDataSegments = false;
+  List<int>? watchPoints = null;
+
+  bool get useRttGlobals => runtimeTypes && !nominalTypes;
+}
+
+typedef CodeGenCallback = void Function(w.Instructions);
+
+/// The main entry point for the translation from kernel to Wasm and the hub for
+/// all global state in the compiler.
+///
+/// This class also contains utility methods for types and code generation used
+/// throughout the compiler.
+class Translator {
+  // Options for the translation.
+  final TranslatorOptions options;
+
+  // Kernel input and context.
+  final Component component;
+  final List<Library> libraries;
+  final CoreTypes coreTypes;
+  final TypeEnvironment typeEnvironment;
+  final ClosedWorldClassHierarchy hierarchy;
+  late final ClassHierarchySubtypes subtypes;
+
+  // Classes and members referenced specifically by the compiler.
+  late final Class wasmTypesBaseClass;
+  late final Class wasmArrayBaseClass;
+  late final Class wasmAnyRefClass;
+  late final Class wasmEqRefClass;
+  late final Class wasmDataRefClass;
+  late final Class boxedBoolClass;
+  late final Class boxedIntClass;
+  late final Class boxedDoubleClass;
+  late final Class functionClass;
+  late final Class listBaseClass;
+  late final Class fixedLengthListClass;
+  late final Class growableListClass;
+  late final Class immutableListClass;
+  late final Class stringBaseClass;
+  late final Class oneByteStringClass;
+  late final Class twoByteStringClass;
+  late final Class typeClass;
+  late final Class typedListBaseClass;
+  late final Class typedListClass;
+  late final Class typedListViewClass;
+  late final Class byteDataViewClass;
+  late final Procedure stringEquals;
+  late final Procedure stringInterpolate;
+  late final Procedure mapFactory;
+  late final Procedure mapPut;
+  late final Map<Class, w.StorageType> builtinTypes;
+  late final Map<w.ValueType, Class> boxedClasses;
+
+  // Other parts of the global compiler state.
+  late final ClassInfoCollector classInfoCollector;
+  late final DispatchTable dispatchTable;
+  late final Globals globals;
+  late final Constants constants;
+  late final FunctionCollector functions;
+
+  // Information about the program used and updated by the various phases.
+  final List<ClassInfo> classes = [];
+  final Map<Class, ClassInfo> classInfo = {};
+  final Map<w.HeapType, ClassInfo> classForHeapType = {};
+  final Map<Field, int> fieldIndex = {};
+  final Map<TypeParameter, int> typeParameterIndex = {};
+  final Map<Reference, ParameterInfo> staticParamInfo = {};
+  late Procedure mainFunction;
+  late final w.Module m;
+  late final w.DefinedFunction initFunction;
+  late final w.ValueType voidMarker;
+
+  // Caches for when identical source constructs need a common representation.
+  final Map<w.StorageType, w.ArrayType> arrayTypeCache = {};
+  final Map<int, w.StructType> functionTypeCache = {};
+  final Map<w.StructType, int> functionTypeParameterCount = {};
+  final Map<int, w.DefinedGlobal> functionTypeRtt = {};
+  final Map<w.DefinedFunction, w.DefinedGlobal> functionRefCache = {};
+  final Map<Procedure, w.DefinedFunction> tearOffFunctionCache = {};
+
+  ClassInfo get topInfo => classes[0];
+  ClassInfo get objectInfo => classInfo[coreTypes.objectClass]!;
+
+  Translator(this.component, this.coreTypes, this.typeEnvironment, this.options)
+      : libraries = component.libraries,
+        hierarchy =
+            ClassHierarchy(component, coreTypes) as ClosedWorldClassHierarchy {
+    subtypes = hierarchy.computeSubtypesInformation();
+    classInfoCollector = ClassInfoCollector(this);
+    dispatchTable = DispatchTable(this);
+    functions = FunctionCollector(this);
+
+    Library coreLibrary =
+        component.libraries.firstWhere((l) => l.name == "dart.core");
+    Class lookupCore(String name) {
+      return coreLibrary.classes.firstWhere((c) => c.name == name);
+    }
+
+    Library collectionLibrary =
+        component.libraries.firstWhere((l) => l.name == "dart.collection");
+    Class lookupCollection(String name) {
+      return collectionLibrary.classes.firstWhere((c) => c.name == name);
+    }
+
+    Library typedDataLibrary =
+        component.libraries.firstWhere((l) => l.name == "dart.typed_data");
+    Class lookupTypedData(String name) {
+      return typedDataLibrary.classes.firstWhere((c) => c.name == name);
+    }
+
+    Library wasmLibrary =
+        component.libraries.firstWhere((l) => l.name == "dart.wasm");
+    Class lookupWasm(String name) {
+      return wasmLibrary.classes.firstWhere((c) => c.name == name);
+    }
+
+    wasmTypesBaseClass = lookupWasm("_WasmBase");
+    wasmArrayBaseClass = lookupWasm("_WasmArray");
+    wasmAnyRefClass = lookupWasm("WasmAnyRef");
+    wasmEqRefClass = lookupWasm("WasmEqRef");
+    wasmDataRefClass = lookupWasm("WasmDataRef");
+    boxedBoolClass = lookupCore("_BoxedBool");
+    boxedIntClass = lookupCore("_BoxedInt");
+    boxedDoubleClass = lookupCore("_BoxedDouble");
+    functionClass = lookupCore("_Function");
+    fixedLengthListClass = lookupCore("_List");
+    listBaseClass = lookupCore("_ListBase");
+    growableListClass = lookupCore("_GrowableList");
+    immutableListClass = lookupCore("_ImmutableList");
+    stringBaseClass = lookupCore("_StringBase");
+    oneByteStringClass = lookupCore("_OneByteString");
+    twoByteStringClass = lookupCore("_TwoByteString");
+    typeClass = lookupCore("_Type");
+    typedListBaseClass = lookupTypedData("_TypedListBase");
+    typedListClass = lookupTypedData("_TypedList");
+    typedListViewClass = lookupTypedData("_TypedListView");
+    byteDataViewClass = lookupTypedData("_ByteDataView");
+    stringEquals =
+        stringBaseClass.procedures.firstWhere((p) => p.name.text == "==");
+    stringInterpolate = stringBaseClass.procedures
+        .firstWhere((p) => p.name.text == "_interpolate");
+    mapFactory = lookupCollection("LinkedHashMap").procedures.firstWhere(
+        (p) => p.kind == ProcedureKind.Factory && p.name.text == "_default");
+    mapPut = lookupCollection("_CompactLinkedCustomHashMap")
+        .superclass! // _HashBase
+        .superclass! // _LinkedHashMapMixin<K, V>
+        .procedures
+        .firstWhere((p) => p.name.text == "[]=");
+    builtinTypes = {
+      coreTypes.boolClass: w.NumType.i32,
+      coreTypes.intClass: w.NumType.i64,
+      coreTypes.doubleClass: w.NumType.f64,
+      wasmAnyRefClass: w.RefType.any(nullable: false),
+      wasmEqRefClass: w.RefType.eq(nullable: false),
+      wasmDataRefClass: w.RefType.data(nullable: false),
+      boxedBoolClass: w.NumType.i32,
+      boxedIntClass: w.NumType.i64,
+      boxedDoubleClass: w.NumType.f64,
+      lookupWasm("WasmI8"): w.PackedType.i8,
+      lookupWasm("WasmI16"): w.PackedType.i16,
+      lookupWasm("WasmI32"): w.NumType.i32,
+      lookupWasm("WasmI64"): w.NumType.i64,
+      lookupWasm("WasmF32"): w.NumType.f32,
+      lookupWasm("WasmF64"): w.NumType.f64,
+    };
+    boxedClasses = {
+      w.NumType.i32: boxedBoolClass,
+      w.NumType.i64: boxedIntClass,
+      w.NumType.f64: boxedDoubleClass,
+    };
+  }
+
+  Uint8List translate() {
+    m = w.Module(watchPoints: options.watchPoints);
+    voidMarker = w.RefType.def(w.StructType("void"), nullable: true);
+
+    classInfoCollector.collect();
+
+    functions.collectImportsAndExports();
+    mainFunction =
+        libraries.first.procedures.firstWhere((p) => p.name.text == "main");
+    functions.addExport(mainFunction.reference, "main");
+
+    initFunction = m.addFunction(functionType(const [], const []), "#init");
+    m.startFunction = initFunction;
+
+    globals = Globals(this);
+    constants = Constants(this);
+
+    dispatchTable.build();
+
+    functions.initialize();
+    while (functions.worklist.isNotEmpty) {
+      Reference reference = functions.worklist.removeLast();
+      Member member = reference.asMember;
+      var function =
+          functions.getExistingFunction(reference) as w.DefinedFunction;
+
+      String canonicalName = "$member";
+      if (reference.isSetter) {
+        canonicalName = "$canonicalName=";
+      } else if (reference.isGetter || reference.isTearOffReference) {
+        int dot = canonicalName.indexOf('.');
+        canonicalName = canonicalName.substring(0, dot + 1) +
+            '=' +
+            canonicalName.substring(dot + 1);
+      }
+      canonicalName = member.enclosingLibrary == libraries.first
+          ? canonicalName
+          : "${member.enclosingLibrary.importUri} $canonicalName";
+
+      String? exportName = functions.exports[reference];
+
+      if (options.printKernel || options.printWasm) {
+        if (exportName != null) {
+          print("#${function.index}: $canonicalName (exported as $exportName)");
+        } else {
+          print("#${function.index}: $canonicalName");
+        }
+        print(member.function
+            ?.computeFunctionType(Nullability.nonNullable)
+            .toStringInternal());
+      }
+      if (options.printKernel) {
+        if (member is Constructor) {
+          Class cls = member.enclosingClass;
+          for (Field field in cls.fields) {
+            if (field.isInstanceMember && field.initializer != null) {
+              print("${field.name}: ${field.initializer}");
+            }
+          }
+          for (Initializer initializer in member.initializers) {
+            print(initializer);
+          }
+        }
+        Statement? body = member.function?.body;
+        if (body != null) {
+          print(body);
+        }
+        if (!options.printWasm) print("");
+      }
+
+      if (exportName != null) {
+        m.exportFunction(exportName, function);
+      } else if (options.exportAll) {
+        m.exportFunction(canonicalName, function);
+      }
+      var codeGen = CodeGenerator(this, function, reference);
+      codeGen.generate();
+
+      if (options.printWasm) {
+        print(function.type);
+        print(function.body.trace);
+      }
+
+      for (Lambda lambda in codeGen.closures.lambdas.values) {
+        CodeGenerator(this, lambda.function, reference)
+            .generateLambda(lambda, codeGen.closures);
+        _printFunction(lambda.function, "$canonicalName (closure)");
+      }
+    }
+
+    dispatchTable.output();
+    constants.finalize();
+    initFunction.body.end();
+
+    for (ConstantInfo info in constants.constantInfo.values) {
+      w.DefinedFunction? function = info.function;
+      if (function != null) {
+        _printFunction(function, info.constant);
+      } else {
+        if (options.printWasm) {
+          print("Global #${info.global.index}: ${info.constant}");
+          print(info.global.initializer.trace);
+        }
+      }
+    }
+    if (options.lazyConstants) {
+      _printFunction(constants.oneByteStringFunction, "makeOneByteString");
+      _printFunction(constants.twoByteStringFunction, "makeTwoByteString");
+    }
+    _printFunction(initFunction, "init");
+
+    return m.encode(emitNameSection: options.nameSection);
+  }
+
+  void _printFunction(w.DefinedFunction function, Object name) {
+    if (options.printWasm) {
+      print("#${function.index}: $name");
+      print(function.body.trace);
+    }
+  }
+
+  Class classForType(DartType type) {
+    return type is InterfaceType
+        ? type.classNode
+        : type is TypeParameterType
+            ? classForType(type.bound)
+            : coreTypes.objectClass;
+  }
+
+  w.ValueType translateType(DartType type) {
+    w.StorageType wasmType = translateStorageType(type);
+    if (wasmType is w.ValueType) return wasmType;
+    throw "Packed types are only allowed in arrays and fields";
+  }
+
+  bool isWasmType(Class cls) {
+    while (cls.superclass != null) {
+      cls = cls.superclass!;
+      if (cls == wasmTypesBaseClass) return true;
+    }
+    return false;
+  }
+
+  w.StorageType typeForInfo(ClassInfo info, bool nullable) {
+    Class? cls = info.cls;
+    if (cls != null) {
+      w.StorageType? builtin = builtinTypes[cls];
+      if (builtin != null) {
+        if (!nullable) return builtin;
+        if (isWasmType(cls)) {
+          if (builtin.isPrimitive) throw "Wasm numeric types can't be nullable";
+          return (builtin as w.RefType).withNullability(true);
+        }
+        Class? boxedClass = boxedClasses[builtin];
+        if (boxedClass != null) {
+          info = classInfo[boxedClass]!;
+        }
+      }
+    }
+    return w.RefType.def(info.repr.struct,
+        nullable: !options.parameterNullability || nullable);
+  }
+
+  w.StorageType translateStorageType(DartType type) {
+    if (type is InterfaceType) {
+      if (type.classNode.superclass == wasmArrayBaseClass) {
+        DartType elementType = type.typeArguments.single;
+        return w.RefType.def(arrayTypeForDartType(elementType),
+            nullable: false);
+      }
+      return typeForInfo(
+          classInfo[type.classNode]!, type.isPotentiallyNullable);
+    }
+    if (type is DynamicType) {
+      return topInfo.nullableType;
+    }
+    if (type is NullType) {
+      return topInfo.nullableType;
+    }
+    if (type is NeverType) {
+      return topInfo.nullableType;
+    }
+    if (type is VoidType) {
+      return voidMarker;
+    }
+    if (type is TypeParameterType) {
+      return translateStorageType(type.isPotentiallyNullable
+          ? type.bound.withDeclaredNullability(type.nullability)
+          : type.bound);
+    }
+    if (type is FutureOrType) {
+      return topInfo.nullableType;
+    }
+    if (type is FunctionType) {
+      if (type.requiredParameterCount != type.positionalParameters.length ||
+          type.namedParameters.isNotEmpty) {
+        throw "Function types with optional parameters not supported: $type";
+      }
+      return w.RefType.def(closureStructType(type.requiredParameterCount),
+          nullable:
+              !options.parameterNullability || type.isPotentiallyNullable);
+    }
+    throw "Unsupported type ${type.runtimeType}";
+  }
+
+  w.ArrayType arrayTypeForDartType(DartType type) {
+    while (type is TypeParameterType) type = type.bound;
+    return wasmArrayType(
+        translateStorageType(type), type.toText(defaultAstTextStrategy));
+  }
+
+  w.ArrayType wasmArrayType(w.StorageType type, String name) {
+    return arrayTypeCache.putIfAbsent(
+        type, () => arrayType("Array<$name>", elementType: w.FieldType(type)));
+  }
+
+  w.StructType closureStructType(int parameterCount) {
+    return functionTypeCache.putIfAbsent(parameterCount, () {
+      ClassInfo info = classInfo[functionClass]!;
+      w.StructType struct = structType("Function$parameterCount",
+          fields: info.struct.fields, superType: info.struct);
+      assert(struct.fields.length == FieldIndex.closureFunction);
+      struct.fields.add(w.FieldType(
+          w.RefType.def(closureFunctionType(parameterCount), nullable: false),
+          mutable: false));
+      if (options.useRttGlobals) {
+        functionTypeRtt[parameterCount] =
+            classInfoCollector.makeRtt(struct, info);
+      }
+      functionTypeParameterCount[struct] = parameterCount;
+      return struct;
+    });
+  }
+
+  w.FunctionType closureFunctionType(int parameterCount) {
+    return functionType([
+      w.RefType.data(),
+      ...List<w.ValueType>.filled(parameterCount, topInfo.nullableType)
+    ], [
+      topInfo.nullableType
+    ]);
+  }
+
+  int parameterCountForFunctionStruct(w.HeapType heapType) {
+    return functionTypeParameterCount[heapType]!;
+  }
+
+  w.DefinedGlobal makeFunctionRef(w.DefinedFunction f) {
+    return functionRefCache.putIfAbsent(f, () {
+      w.DefinedGlobal global = m.addGlobal(
+          w.GlobalType(w.RefType.def(f.type, nullable: false), mutable: false));
+      global.initializer.ref_func(f);
+      global.initializer.end();
+      return global;
+    });
+  }
+
+  w.DefinedFunction getTearOffFunction(Procedure member) {
+    return tearOffFunctionCache.putIfAbsent(member, () {
+      assert(member.kind == ProcedureKind.Method);
+      FunctionNode functionNode = member.function;
+      int parameterCount = functionNode.requiredParameterCount;
+      if (functionNode.positionalParameters.length != parameterCount ||
+          functionNode.namedParameters.isNotEmpty) {
+        throw "Not supported: Tear-off with optional parameters"
+            " at ${member.location}";
+      }
+      if (functionNode.typeParameters.isNotEmpty) {
+        throw "Not supported: Tear-off with type parameters"
+            " at ${member.location}";
+      }
+      w.FunctionType memberSignature = signatureFor(member.reference);
+      w.FunctionType closureSignature = closureFunctionType(parameterCount);
+      int signatureOffset = member.isInstanceMember ? 1 : 0;
+      assert(memberSignature.inputs.length == signatureOffset + parameterCount);
+      assert(closureSignature.inputs.length == 1 + parameterCount);
+      w.DefinedFunction function =
+          m.addFunction(closureSignature, "$member (tear-off)");
+      w.BaseFunction target = functions.getFunction(member.reference);
+      w.Instructions b = function.body;
+      for (int i = 0; i < memberSignature.inputs.length; i++) {
+        w.Local paramLocal = function.locals[(1 - signatureOffset) + i];
+        b.local_get(paramLocal);
+        convertType(function, paramLocal.type, memberSignature.inputs[i]);
+      }
+      b.call(target);
+      convertType(function, outputOrVoid(target.type.outputs),
+          outputOrVoid(closureSignature.outputs));
+      b.end();
+      return function;
+    });
+  }
+
+  w.ValueType ensureBoxed(w.ValueType type) {
+    // Box receiver if it's primitive
+    if (type is w.RefType) return type;
+    return w.RefType.def(classInfo[boxedClasses[type]!]!.struct,
+        nullable: false);
+  }
+
+  w.ValueType typeForLocal(w.ValueType type) {
+    return options.localNullability ? type : type.withNullability(true);
+  }
+
+  w.ValueType outputOrVoid(List<w.ValueType> outputs) {
+    return outputs.isEmpty ? voidMarker : outputs.single;
+  }
+
+  bool needsConversion(w.ValueType from, w.ValueType to) {
+    return (from == voidMarker) ^ (to == voidMarker) || !from.isSubtypeOf(to);
+  }
+
+  void convertType(
+      w.DefinedFunction function, w.ValueType from, w.ValueType to) {
+    w.Instructions b = function.body;
+    if (from == voidMarker || to == voidMarker) {
+      if (from != voidMarker) {
+        b.drop();
+        return;
+      }
+      if (to != voidMarker) {
+        if (to is w.RefType && to.nullable) {
+          // This can happen when a void method has its return type overridden to
+          // return a value, in which case the selector signature will have a
+          // non-void return type to encompass all possible return values.
+          b.ref_null(to.heapType);
+        } else {
+          // This only happens in invalid but unreachable code produced by the
+          // TFA dead-code elimination.
+          b.comment("Non-nullable void conversion");
+          b.unreachable();
+        }
+        return;
+      }
+    }
+    if (!from.isSubtypeOf(to)) {
+      if (from is! w.RefType && to is w.RefType) {
+        // Boxing
+        ClassInfo info = classInfo[boxedClasses[from]!]!;
+        assert(info.struct.isSubtypeOf(to.heapType));
+        w.Local temp = function.addLocal(from);
+        b.local_set(temp);
+        b.i32_const(info.classId);
+        b.local_get(temp);
+        struct_new(b, info);
+      } else if (from is w.RefType && to is! w.RefType) {
+        // Unboxing
+        ClassInfo info = classInfo[boxedClasses[to]!]!;
+        if (!from.heapType.isSubtypeOf(info.struct)) {
+          // Cast to box type
+          if (!from.heapType.isSubtypeOf(w.HeapType.data)) {
+            b.ref_as_data();
+          }
+          ref_cast(b, info);
+        }
+        b.struct_get(info.struct, FieldIndex.boxValue);
+      } else if (from.withNullability(false).isSubtypeOf(to)) {
+        // Null check
+        b.ref_as_non_null();
+      } else {
+        // Downcast
+        var heapType = (to as w.RefType).heapType;
+        ClassInfo? info = classForHeapType[heapType];
+        if (from.nullable && !to.nullable) {
+          b.ref_as_non_null();
+        }
+        if (!(from as w.RefType).heapType.isSubtypeOf(w.HeapType.data)) {
+          b.ref_as_data();
+        }
+        ref_cast(
+            b,
+            info ??
+                (heapType.isSubtypeOf(classInfo[functionClass]!.struct)
+                    ? parameterCountForFunctionStruct(heapType)
+                    : heapType));
+      }
+    }
+  }
+
+  w.FunctionType signatureFor(Reference target) {
+    Member member = target.asMember;
+    if (member.isInstanceMember) {
+      return dispatchTable.selectorForTarget(target).signature;
+    } else {
+      return functions.getFunction(target).type;
+    }
+  }
+
+  ParameterInfo paramInfoFor(Reference target) {
+    Member member = target.asMember;
+    if (member.isInstanceMember) {
+      return dispatchTable.selectorForTarget(target).paramInfo;
+    } else {
+      return staticParamInfo.putIfAbsent(
+          target, () => ParameterInfo.fromMember(target));
+    }
+  }
+
+  Member? singleTarget(TreeNode node) {
+    DirectCallMetadataRepository metadata =
+        component.metadata[DirectCallMetadataRepository.repositoryTag]
+            as DirectCallMetadataRepository;
+    return metadata.mapping[node]?.target;
+  }
+
+  bool shouldInline(Reference target) {
+    if (!options.inlining) return false;
+    Member member = target.asMember;
+    if (member is Field) return true;
+    Statement? body = member.function!.body;
+    return body != null &&
+        NodeCounter().countNodes(body) <= options.inliningLimit;
+  }
+
+  T? getPragma<T>(Annotatable node, String name, [T? defaultvalue]) {
+    for (Expression annotation in node.annotations) {
+      if (annotation is ConstantExpression) {
+        Constant constant = annotation.constant;
+        if (constant is InstanceConstant) {
+          if (constant.classNode == coreTypes.pragmaClass) {
+            Constant? nameConstant =
+                constant.fieldValues[coreTypes.pragmaName.fieldReference];
+            if (nameConstant is StringConstant && nameConstant.value == name) {
+              Object? value =
+                  constant.fieldValues[coreTypes.pragmaOptions.fieldReference];
+              if (value is PrimitiveConstant<T>) {
+                return value.value;
+              }
+              return value as T? ?? defaultvalue;
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  // Wrappers for type creation to abstract over equi-recursive versus nominal
+  // typing. The given supertype is ignored when nominal types are disabled,
+  // and a suitable default is inserted when nominal types are enabled.
+
+  w.FunctionType functionType(
+      Iterable<w.ValueType> inputs, Iterable<w.ValueType> outputs,
+      {w.HeapType? superType}) {
+    return m.addFunctionType(inputs, outputs,
+        superType: options.nominalTypes ? superType ?? w.HeapType.func : null);
+  }
+
+  w.StructType structType(String name,
+      {Iterable<w.FieldType>? fields, w.HeapType? superType}) {
+    return m.addStructType(name,
+        fields: fields,
+        superType: options.nominalTypes ? superType ?? w.HeapType.data : null);
+  }
+
+  w.ArrayType arrayType(String name,
+      {w.FieldType? elementType, w.HeapType? superType}) {
+    return m.addArrayType(name,
+        elementType: elementType,
+        superType: options.nominalTypes ? superType ?? w.HeapType.data : null);
+  }
+
+  // Wrappers for object allocation and cast instructions to abstract over
+  // RTT-based and static versions of the instructions.
+  // The [type] parameter taken by the methods is either a [ClassInfo] (to use
+  // the RTT for the class), an [int] (to use the RTT for the closure struct
+  // corresponding to functions with that number of parameters) or a
+  // [w.DataType] (to use the canonical RTT for the type).
+
+  void struct_new(w.Instructions b, Object type) {
+    if (options.runtimeTypes) {
+      final struct = _emitRtt(b, type) as w.StructType;
+      b.struct_new_with_rtt(struct);
+    } else {
+      b.struct_new(_targetType(type) as w.StructType);
+    }
+  }
+
+  void struct_new_default(w.Instructions b, Object type) {
+    if (options.runtimeTypes) {
+      final struct = _emitRtt(b, type) as w.StructType;
+      b.struct_new_default_with_rtt(struct);
+    } else {
+      b.struct_new_default(_targetType(type) as w.StructType);
+    }
+  }
+
+  void array_new(w.Instructions b, w.ArrayType type) {
+    if (options.runtimeTypes) {
+      b.rtt_canon(type);
+      b.array_new_with_rtt(type);
+    } else {
+      b.array_new(type);
+    }
+  }
+
+  void array_new_default(w.Instructions b, w.ArrayType type) {
+    if (options.runtimeTypes) {
+      b.rtt_canon(type);
+      b.array_new_default_with_rtt(type);
+    } else {
+      b.array_new_default(type);
+    }
+  }
+
+  void array_init(w.Instructions b, w.ArrayType type, int length) {
+    if (options.runtimeTypes) {
+      b.rtt_canon(type);
+      b.array_init(type, length);
+    } else {
+      b.array_init_static(type, length);
+    }
+  }
+
+  void array_init_from_data(
+      w.Instructions b, w.ArrayType type, w.DataSegment data) {
+    if (options.runtimeTypes) {
+      b.rtt_canon(type);
+      b.array_init_from_data(type, data);
+    } else {
+      b.array_init_from_data_static(type, data);
+    }
+  }
+
+  void ref_test(w.Instructions b, Object type) {
+    if (options.runtimeTypes) {
+      _emitRtt(b, type);
+      b.ref_test();
+    } else {
+      b.ref_test_static(_targetType(type));
+    }
+  }
+
+  void ref_cast(w.Instructions b, Object type) {
+    if (options.runtimeTypes) {
+      _emitRtt(b, type);
+      b.ref_cast();
+    } else {
+      b.ref_cast_static(_targetType(type));
+    }
+  }
+
+  void br_on_cast(w.Instructions b, w.Label label, Object type) {
+    if (options.runtimeTypes) {
+      _emitRtt(b, type);
+      b.br_on_cast(label);
+    } else {
+      b.br_on_cast_static(label, _targetType(type));
+    }
+  }
+
+  void br_on_cast_fail(w.Instructions b, w.Label label, Object type) {
+    if (options.runtimeTypes) {
+      _emitRtt(b, type);
+      b.br_on_cast_fail(label);
+    } else {
+      b.br_on_cast_static_fail(label, _targetType(type));
+    }
+  }
+
+  w.DefType _emitRtt(w.Instructions b, Object type) {
+    if (type is ClassInfo) {
+      if (options.nominalTypes) {
+        b.rtt_canon(type.struct);
+      } else {
+        b.global_get(type.rtt);
+      }
+      return type.struct;
+    } else if (type is int) {
+      int parameterCount = type;
+      w.StructType struct = closureStructType(parameterCount);
+      if (options.nominalTypes) {
+        b.rtt_canon(struct);
+      } else {
+        w.DefinedGlobal rtt = functionTypeRtt[parameterCount]!;
+        b.global_get(rtt);
+      }
+      return struct;
+    } else {
+      b.rtt_canon(type as w.DataType);
+      return type;
+    }
+  }
+
+  w.DefType _targetType(Object type) => type is ClassInfo
+      ? type.struct
+      : type is int
+          ? closureStructType(type)
+          : type as w.DefType;
+}
+
+class NodeCounter extends Visitor<void> with VisitorVoidMixin {
+  int count = 0;
+
+  int countNodes(Node node) {
+    count = 0;
+    node.accept(this);
+    return count;
+  }
+
+  @override
+  void defaultNode(Node node) {
+    count++;
+    node.visitChildren(this);
+  }
+}
diff --git a/pkg/dart2wasm/pubspec.yaml b/pkg/dart2wasm/pubspec.yaml
new file mode 100644
index 0000000..dd0b8de
--- /dev/null
+++ b/pkg/dart2wasm/pubspec.yaml
@@ -0,0 +1,26 @@
+name: dart2wasm
+# This package is not intended for consumption on pub.dev. DO NOT publish.
+publish_to: none
+environment:
+  sdk: '>=2.12.0'
+
+dependencies:
+  front_end:
+    path: ../front_end
+  kernel:
+    path: ../kernel
+  vm:
+    path: ../vm
+  wasm_builder:
+    path: ../wasm_builder
+
+dependency_overrides:
+  # Packages with source in the SDK
+  front_end:
+    path: ../front_end
+  kernel:
+    path: ../kernel
+  vm:
+    path: ../vm
+  wasm_builder:
+    path: ../wasm_builder
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 7952b4b..755208c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -422,6 +422,17 @@
     }, () => loader.currentUriForCrashReporting);
   }
 
+  /// Builds [augmentationLibraries] to the state expected after applying phase
+  /// 1 macros.
+  Future<void> _buildForPhase1(
+      Iterable<SourceLibraryBuilder> augmentationLibraries) async {
+    await loader.buildOutlines();
+    loader.computeLibraryScopes(augmentationLibraries);
+    // TODO(johnniwinther): Support computation of macro applications in
+    // augmentation libraries?
+    loader.resolveTypes(augmentationLibraries);
+  }
+
   Future<BuildResult> buildOutlines({CanonicalName? nameRoot}) async {
     if (loader.first == null) return new BuildResult();
     return withCrashReporting<BuildResult>(() async {
@@ -441,7 +452,7 @@
       }
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_computeLibraryScopes);
-      loader.computeLibraryScopes();
+      loader.computeLibraryScopes(loader.libraryBuilders);
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_computeMacroApplications);
       MacroApplications? macroApplications =
@@ -451,10 +462,10 @@
       setupTopAndBottomTypes();
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_resolveTypes);
-      loader.resolveTypes();
+      loader.resolveTypes(loader.sourceLibraryBuilders);
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_computeVariances);
-      loader.computeVariances();
+      loader.computeVariances(loader.sourceLibraryBuilders);
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_computeDefaultTypes);
       loader.computeDefaultTypes(
@@ -462,7 +473,9 @@
 
       if (macroApplications != null) {
         benchmarker?.enterPhase(BenchmarkPhases.outline_applyTypeMacros);
-        await macroApplications.applyTypeMacros();
+        List<SourceLibraryBuilder> augmentationLibraries =
+            await macroApplications.applyTypeMacros();
+        await _buildForPhase1(augmentationLibraries);
       }
 
       benchmarker?.enterPhase(BenchmarkPhases.outline_checkSemantics);
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index c14a5cd..6f6abea 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -78,12 +78,14 @@
 
 class MacroApplicationDataForTesting {
   Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
-  Map<SourceClassBuilder, String> classTypesResults = {};
+  Map<SourceLibraryBuilder, String> libraryTypesResult = {};
+  Map<SourceClassBuilder, List<macro.MacroExecutionResult>> classTypesResults =
+      {};
   Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
       classDeclarationsResults = {};
   Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
       classDefinitionsResults = {};
-  Map<MemberBuilder, String> memberTypesResults = {};
+  Map<MemberBuilder, List<macro.MacroExecutionResult>> memberTypesResults = {};
   Map<MemberBuilder, List<macro.MacroExecutionResult>>
       memberDeclarationsResults = {};
   Map<MemberBuilder, List<macro.MacroExecutionResult>>
@@ -235,6 +237,8 @@
           uri = typeDeclarationBuilder.library.importUri;
         } else if (typeDeclarationBuilder is TypeAliasBuilder) {
           uri = typeDeclarationBuilder.library.importUri;
+        } else if (identifier.name == 'dynamic') {
+          uri = Uri.parse('dart:core');
         }
         return new macro.ResolvedIdentifier(
             kind: macro.IdentifierKind.topLevelMember,
@@ -252,19 +256,33 @@
       }
     } else {
       // TODO(johnniwinther): Use [_IdentifierImpl] for all identifiers.
-      return new macro.ResolvedIdentifier(
-          kind: macro.IdentifierKind.topLevelMember,
-          name: identifier.name,
-          staticScope: null,
-          uri: null);
+      if (identical(identifier, dynamicIdentifier)) {
+        return new macro.ResolvedIdentifier(
+            kind: macro.IdentifierKind.topLevelMember,
+            name: identifier.name,
+            staticScope: null,
+            uri: Uri.parse('dart:core'));
+      } else {
+        return new macro.ResolvedIdentifier(
+            kind: macro.IdentifierKind.topLevelMember,
+            name: identifier.name,
+            staticScope: null,
+            uri: null);
+      }
     }
   }
 
-  Future<void> _applyMacros(
-      Future<void> Function(Builder, macro.Declaration, List<MacroApplication>)
-          applyMacros) async {
+  Future<Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>>>
+      _applyMacros(
+          Future<List<macro.MacroExecutionResult>> Function(
+                  Builder, macro.Declaration, List<MacroApplication>)
+              applyMacros) async {
+    Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>> libraryResults =
+        {};
     for (MapEntry<SourceLibraryBuilder,
         LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
+      SourceLibraryBuilder libraryBuilder = libraryEntry.key;
+      List<macro.MacroExecutionResult> results = [];
       LibraryMacroApplicationData libraryMacroApplicationData =
           libraryEntry.value;
       for (MapEntry<MemberBuilder, List<MacroApplication>> memberEntry
@@ -272,7 +290,8 @@
         MemberBuilder memberBuilder = memberEntry.key;
         macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
         if (declaration != null) {
-          await applyMacros(memberBuilder, declaration, memberEntry.value);
+          results.addAll(
+              await applyMacros(memberBuilder, declaration, memberEntry.value));
         }
       }
       for (MapEntry<SourceClassBuilder, ClassMacroApplicationData> classEntry
@@ -283,18 +302,22 @@
         if (classApplications != null) {
           macro.ClassDeclaration classDeclaration =
               _getClassDeclaration(classBuilder);
-          await applyMacros(classBuilder, classDeclaration, classApplications);
+          results.addAll(await applyMacros(
+              classBuilder, classDeclaration, classApplications));
         }
         for (MapEntry<MemberBuilder, List<MacroApplication>> memberEntry
             in classData.memberApplications.entries) {
           MemberBuilder memberBuilder = memberEntry.key;
           macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
           if (declaration != null) {
-            await applyMacros(memberBuilder, declaration, memberEntry.value);
+            results.addAll(await applyMacros(
+                memberBuilder, declaration, memberEntry.value));
           }
         }
       }
+      libraryResults[libraryBuilder] = results;
     }
+    return libraryResults;
   }
 
   Future<List<macro.MacroExecutionResult>> _applyTypeMacros(
@@ -311,20 +334,33 @@
         results.add(result);
       }
     }
-    String result =
-        _macroExecutor.buildAugmentationLibrary(results, _resolveIdentifier);
+
     if (retainDataForTesting) {
       if (builder is SourceClassBuilder) {
-        dataForTesting?.classTypesResults[builder] = result;
+        dataForTesting?.classTypesResults[builder] = results;
       } else {
-        dataForTesting?.memberTypesResults[builder as MemberBuilder] = result;
+        dataForTesting?.memberTypesResults[builder as MemberBuilder] = results;
       }
     }
     return results;
   }
 
-  Future<void> applyTypeMacros() async {
-    await _applyMacros(_applyTypeMacros);
+  Future<List<SourceLibraryBuilder>> applyTypeMacros() async {
+    List<SourceLibraryBuilder> augmentationLibraries = [];
+    Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>> results =
+        await _applyMacros(_applyTypeMacros);
+    for (MapEntry<SourceLibraryBuilder, List<macro.MacroExecutionResult>> entry
+        in results.entries) {
+      SourceLibraryBuilder sourceLibraryBuilder = entry.key;
+      String result = _macroExecutor.buildAugmentationLibrary(
+          entry.value, _resolveIdentifier);
+      if (retainDataForTesting) {
+        dataForTesting?.libraryTypesResult[sourceLibraryBuilder] = result;
+      }
+      augmentationLibraries
+          .add(await sourceLibraryBuilder.createAugmentationLibrary(result));
+    }
+    return augmentationLibraries;
   }
 
   Future<List<macro.MacroExecutionResult>> _applyDeclarationsMacros(
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index a5a4d57..70e9378 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -504,6 +504,28 @@
     (_patchLibraries ??= []).add(patchLibrary);
   }
 
+  /// Creates a synthesized augmentation library for the [source] code and
+  /// attach it as a patch library of this library.
+  ///
+  /// To support the parser of the [source], the library is registered as an
+  /// unparsed library on the [loader].
+  SourceLibraryBuilder createAugmentationLibrary(String source) {
+    int index = _patchLibraries?.length ?? 0;
+    Uri uri = new Uri(
+        scheme: 'org-dartlang-augmentation', path: '${fileUri.path}-$index');
+    SourceLibraryBuilder augmentationLibrary = new SourceLibraryBuilder(
+        fileUri: uri,
+        importUri: uri,
+        packageLanguageVersion: packageLanguageVersion,
+        loader: loader,
+        isUnsupported: false,
+        target: library,
+        origin: this);
+    addPatchLibrary(augmentationLibrary);
+    loader.registerUnparsedLibrarySource(augmentationLibrary, source);
+    return augmentationLibrary;
+  }
+
   List<NamedTypeBuilder> get unresolvedNamedTypes =>
       _libraryTypeParameterScopeBuilder.unresolvedNamedTypes;
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 3130c75..a429ef0 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -160,7 +160,8 @@
 
   List<SourceLibraryBuilder>? _sourceLibraryBuilders;
 
-  final Queue<LibraryBuilder> _unparsedLibraries = new Queue<LibraryBuilder>();
+  final Queue<SourceLibraryBuilder> _unparsedLibraries =
+      new Queue<SourceLibraryBuilder>();
 
   final List<Library> libraries = <Library>[];
 
@@ -964,12 +965,25 @@
     _typeInferenceEngine!.typeDependencies[member] = typeDependency;
   }
 
+  /// Registers the [library] as unparsed with the given [source] code.
+  ///
+  /// This is used for creating synthesized augmentation libraries.
+  void registerUnparsedLibrarySource(
+      SourceLibraryBuilder library, String source) {
+    List<int> codeUnits = source.codeUnits;
+    Uint8List bytes = new Uint8List(codeUnits.length + 1);
+    bytes.setRange(0, codeUnits.length, codeUnits);
+    sourceBytes[library.fileUri] = bytes;
+    _unparsedLibraries.addLast(library);
+  }
+
+  /// Runs the [OutlineBuilder] on the source of all [_unparsedLibraries].
   Future<void> buildOutlines() async {
     _ensureCoreLibrary();
     while (_unparsedLibraries.isNotEmpty) {
-      LibraryBuilder library = _unparsedLibraries.removeFirst();
+      SourceLibraryBuilder library = _unparsedLibraries.removeFirst();
       currentUriForCrashReporting = library.importUri;
-      await buildOutline(library as SourceLibraryBuilder);
+      await buildOutline(library);
     }
     currentUriForCrashReporting = null;
     logSummary(outlineSummaryTemplate);
@@ -1256,7 +1270,8 @@
     ticker.logMs("Applied patches");
   }
 
-  void computeLibraryScopes() {
+  /// Compute library scopes for [libraryBuilders].
+  void computeLibraryScopes(Iterable<LibraryBuilder> libraryBuilders) {
     Set<LibraryBuilder> exporters = new Set<LibraryBuilder>();
     Set<LibraryBuilder> exportees = new Set<LibraryBuilder>();
     for (LibraryBuilder library in libraryBuilders) {
@@ -1347,9 +1362,10 @@
     });
   }
 
-  void resolveTypes() {
+  /// Resolve [NamedTypeBuilder]s in [libraryBuilders].
+  void resolveTypes(Iterable<SourceLibraryBuilder> libraryBuilders) {
     int typeCount = 0;
-    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+    for (SourceLibraryBuilder library in libraryBuilders) {
       typeCount += library.resolveTypes();
     }
     ticker.logMs("Resolved $typeCount types");
@@ -1697,9 +1713,10 @@
     ticker.logMs("Resolved $count type-variable bounds");
   }
 
-  void computeVariances() {
+  /// Computes variances of type parameters on typedefs in [libraryBuilders].
+  void computeVariances(Iterable<SourceLibraryBuilder> libraryBuilders) {
     int count = 0;
-    for (SourceLibraryBuilder library in sourceLibraryBuilders) {
+    for (SourceLibraryBuilder library in libraryBuilders) {
       count += library.computeVariances();
     }
     ticker.logMs("Computed variances of $count type variables");
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index 6c2620b..407f814 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -114,9 +114,13 @@
   }
 }
 
+const String _testUriScheme = 'org-dartlang-test';
+
+bool isTestUri(Uri uri) => uri.isScheme(_testUriScheme);
+
 /// A fake absolute directory used as the root of a memory-file system in the
 /// helpers above.
-Uri _defaultDir = Uri.parse('org-dartlang-test:///a/b/c/');
+Uri _defaultDir = Uri.parse('${_testUriScheme}:///a/b/c/');
 
 /// Convert relative file paths into an absolute Uri as expected by the test
 /// helpers above.
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index 48fe099..be478b3 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -85,6 +85,10 @@
   dynamic customizeCompilerOptions(
           CompilerOptions options, TestData testData) =>
       null;
+
+  /// Called after running test on [testData] with the resulting
+  /// [testResultData].
+  void onCompilationResult(TestData testData, TestResultData testResultData) {}
 }
 
 abstract class DataComputer<T> {
@@ -369,6 +373,7 @@
 
   TestResultData testResultData =
       new TestResultData(config, customData, compilerResult);
+  config.onCompilationResult(testData, testResultData);
 
   Component component = compilerResult.component!;
   Map<Uri, Map<Id, ActualData<T>>> actualMaps = <Uri, Map<Id, ActualData<T>>>{};
diff --git a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
index a394202..5f4db94 100644
--- a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
+++ b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
@@ -48,8 +48,10 @@
       TypeBuilder builder) {
     var name = '${function.identifier.name}GeneratedClass';
     builder.declareType(
-        name, new DeclarationCode.fromParts(['class $name<T extends ',
-      function.returnType.code, '> {}']));
+        name, new DeclarationCode.fromParts(['''
+class $name {
+  external ''', function.returnType.code, ''' method();
+}''']));
   }
 }
 
diff --git a/pkg/front_end/test/macro_application/data/tests/declarations.dart b/pkg/front_end/test/macro_application/data/tests/declarations.dart
index 0f95ed9..dfed26d 100644
--- a/pkg/front_end/test/macro_application/data/tests/declarations.dart
+++ b/pkg/front_end/test/macro_application/data/tests/declarations.dart
@@ -2,66 +2,62 @@
 // 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.
 
+/*library: 
+
+
+*/
+
 import 'package:macro/macro.dart';
 
 /*member: topLevelFunction1:
-
 void topLevelFunction1GeneratedMethod_() {}
 */
 @FunctionDeclarationsMacro1()
 void topLevelFunction1() {}
 
 /*member: topLevelFunction2:
-
 void topLevelFunction2GeneratedMethod_e() {}
 */
 @FunctionDeclarationsMacro1()
 external void topLevelFunction2();
 
 /*member: topLevelField1:
-
 void topLevelField1GeneratedMethod_() {}
 */
 @VariableDeclarationsMacro1()
 int? topLevelField1;
 
 /*member: topLevelField2:
-
 void topLevelField2GeneratedMethod_e() {}
 */
 @VariableDeclarationsMacro1()
 external int? topLevelField2;
 
 /*member: topLevelField3:
-
 void topLevelField3GeneratedMethod_f() {}
 */
 @VariableDeclarationsMacro1()
 final int? topLevelField3 = null;
 
 /*member: topLevelField4:
-
 void topLevelField4GeneratedMethod_l() {}
 */
 @VariableDeclarationsMacro1()
 late int? topLevelField4;
 
 /*member: topLevelGetter1:
-
 void topLevelGetter1GeneratedMethod_g() {}
 */
 @FunctionDeclarationsMacro1()
 int? get topLevelGetter1 => null;
 
 /*member: topLevelSetter1=:
-
 void topLevelSetter1GeneratedMethod_s() {}
 */
 @FunctionDeclarationsMacro1()
 void set topLevelSetter1(int? value) {}
 
 /*class: Class1:
-
 void Class1GeneratedMethod_() {}
 
 void Class1Introspection() {
@@ -74,7 +70,6 @@
 @ClassDeclarationsMacro2()
 class Class1 {
   /*member: Class1.:
-
 augment class Class1 {
 void Class1_GeneratedMethod_() {}
 
@@ -83,7 +78,6 @@
   Class1();
 
   /*member: Class1.redirect:
-
 augment class Class1 {
 void Class1_redirectGeneratedMethod_f() {}
 
@@ -92,7 +86,6 @@
   factory Class1.redirect() = Class1;
 
   /*member: Class1.fact:
-
 augment class Class1 {
 void Class1_factGeneratedMethod_f() {}
 
@@ -101,49 +94,42 @@
   factory Class1.fact() => new Class1();
 
   /*member: Class1.instanceMethod1:
-
 void Class1_instanceMethod1GeneratedMethod_() {}
 */
   @MethodDeclarationsMacro1()
   void instanceMethod1() {}
 
   /*member: Class1.instanceGetter1:
-
 void Class1_instanceGetter1GeneratedMethod_g() {}
 */
   @MethodDeclarationsMacro1()
   int? get instanceGetter1 => null;
 
   /*member: Class1.instanceSetter1=:
-
 void Class1_instanceSetter1GeneratedMethod_s() {}
 */
   @MethodDeclarationsMacro1()
   void set instanceSetter1(int? value) {}
 
   /*member: Class1.[]:
-
 void Class1_[]GeneratedMethod_o() {}
 */
   @MethodDeclarationsMacro1()
   int operator [](int i) => i;
 
   /*member: Class1.instanceField1:
-
 void Class1_instanceField1GeneratedMethod_() {}
 */
   @FieldDeclarationsMacro1()
   int? instanceField1;
 
   /*member: Class1.instanceField2:
-
 void Class1_instanceField2GeneratedMethod_f() {}
 */
   @FieldDeclarationsMacro1()
   final int? instanceField2 = null;
 
   /*member: Class1.instanceField3:
-
 void Class1_instanceField3GeneratedMethod_fl() {}
 */
   @FieldDeclarationsMacro1()
@@ -151,7 +137,6 @@
 }
 
 /*class: Class2:
-
 void Class2GeneratedMethod_a() {}
 
 void Class2Introspection() {
@@ -164,14 +149,12 @@
 @ClassDeclarationsMacro2()
 abstract class Class2 {
   /*member: Class2.instanceMethod1:
-
 void Class2_instanceMethod1GeneratedMethod_a() {}
 */
   @MethodDeclarationsMacro1()
   void instanceMethod1();
 
   /*member: Class2.instanceField1:
-
 void Class2_instanceField1GeneratedMethod_() {}
 */
   @FieldDeclarationsMacro1()
diff --git a/pkg/front_end/test/macro_application/data/tests/declarations.dart.expect b/pkg/front_end/test/macro_application/data/tests/declarations.dart.expect
new file mode 100644
index 0000000..786028f
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/declarations.dart.expect
@@ -0,0 +1,81 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "package:macro/macro.dart" as mac;
+import "dart:core" as core;
+
+import "package:macro/macro.dart";
+
+@#C1
+@#C2
+class Class1 extends core::Object {
+  @#C3
+  field core::int? instanceField1 = null;
+  @#C3
+  final field core::int? instanceField2 = null;
+  @#C3
+  late final field core::int? instanceField3 = null;
+  static final field dynamic _redirecting# = <dynamic>[#C4]/*isLegacy*/;
+  @#C5
+  constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  @#C5
+  static factory redirect() → self::Class1
+    return new self::Class1::•();
+  @#C5
+  static factory fact() → self::Class1
+    return new self::Class1::•();
+  @#C6
+  method instanceMethod1() → void {}
+  @#C6
+  get instanceGetter1() → core::int?
+    return null;
+  @#C6
+  set instanceSetter1(core::int? value) → void {}
+  @#C6
+  operator [](core::int i) → core::int
+    return i;
+}
+@#C1
+@#C2
+abstract class Class2 extends core::Object {
+  synthetic constructor •() → self::Class2
+    : super core::Object::•()
+    ;
+  @#C6
+  abstract method instanceMethod1() → void;
+  @#C3
+  abstract get instanceField1() → core::int?;
+  @#C3
+  abstract set instanceField1(core::int? #externalFieldValue) → void;
+}
+@#C7
+static field core::int? topLevelField1;
+@#C7
+static final field core::int? topLevelField3 = null;
+@#C7
+late static field core::int? topLevelField4;
+@#C8
+static method topLevelFunction1() → void {}
+@#C8
+external static method topLevelFunction2() → void;
+@#C7
+external static get topLevelField2() → core::int?;
+@#C7
+external static set topLevelField2(core::int? #externalFieldValue) → void;
+@#C8
+static get topLevelGetter1() → core::int?
+  return null;
+@#C8
+static set topLevelSetter1(core::int? value) → void {}
+
+constants  {
+  #C1 = mac::ClassDeclarationsMacro1 {}
+  #C2 = mac::ClassDeclarationsMacro2 {}
+  #C3 = mac::FieldDeclarationsMacro1 {}
+  #C4 = constructor-tearoff self::Class1::redirect
+  #C5 = mac::ConstructorDeclarationsMacro1 {}
+  #C6 = mac::MethodDeclarationsMacro1 {}
+  #C7 = mac::VariableDeclarationsMacro1 {}
+  #C8 = mac::FunctionDeclarationsMacro1 {}
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/parameters.dart b/pkg/front_end/test/macro_application/data/tests/parameters.dart
index 132979a..89fa87e 100644
--- a/pkg/front_end/test/macro_application/data/tests/parameters.dart
+++ b/pkg/front_end/test/macro_application/data/tests/parameters.dart
@@ -2,10 +2,14 @@
 // 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.
 
+/*library: 
+
+
+*/
+
 import 'package:macro/macro.dart';
 
 /*member: topLevelFunction1:
-
 augment void topLevelFunction1(int a, ) {
   return 42;
 }*/
@@ -13,7 +17,6 @@
 external void topLevelFunction1(int a);
 
 /*member: topLevelFunction2:
-
 augment void topLevelFunction2(int a, int b, ) {
   return 42;
 }*/
@@ -21,7 +24,6 @@
 external void topLevelFunction2(int a, int b);
 
 /*member: topLevelFunction3:
-
 augment void topLevelFunction3(int a, [int? b, ]) {
   return 42;
 }*/
@@ -29,7 +31,6 @@
 external void topLevelFunction3(int a, [int? b]);
 
 /*member: topLevelFunction4:
-
 augment void topLevelFunction4(int a, {int? b, int? c, }) {
   return 42;
 }*/
diff --git a/pkg/front_end/test/macro_application/data/tests/parameters.dart.expect b/pkg/front_end/test/macro_application/data/tests/parameters.dart.expect
new file mode 100644
index 0000000..8f916e5
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/parameters.dart.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "package:macro/macro.dart" as mac;
+import "dart:core" as core;
+
+import "package:macro/macro.dart";
+
+@#C1
+external static method topLevelFunction1(core::int a) → void;
+@#C1
+external static method topLevelFunction2(core::int a, core::int b) → void;
+@#C1
+external static method topLevelFunction3(core::int a, [core::int? b = #C2]) → void;
+@#C1
+external static method topLevelFunction4(core::int a, {core::int? b = #C2, core::int? c = #C2}) → void;
+
+constants  {
+  #C1 = mac::FunctionDefinitionMacro1 {}
+  #C2 = null
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/subtypes.dart b/pkg/front_end/test/macro_application/data/tests/subtypes.dart
index aae13edd..ffdd9f7 100644
--- a/pkg/front_end/test/macro_application/data/tests/subtypes.dart
+++ b/pkg/front_end/test/macro_application/data/tests/subtypes.dart
@@ -2,6 +2,11 @@
 // 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.
 
+/*library: 
+
+
+*/
+
 import 'package:macro/macro.dart';
 
 class A {}
@@ -19,7 +24,6 @@
 class D2 {}
 
 /*member: topLevelFunction1:
-
 void topLevelFunction1GeneratedMethod_es() {}
 
 augment A topLevelFunction1(A a, ) {
@@ -31,7 +35,6 @@
 external A topLevelFunction1(A a);
 
 /*member: topLevelFunction2:
-
 void topLevelFunction2GeneratedMethod_s() {}
 
 augment B2 topLevelFunction2(B1 a, ) {
@@ -43,7 +46,6 @@
 external B2 topLevelFunction2(B1 a);
 
 /*member: topLevelFunction3:
-
 void topLevelFunction3GeneratedMethod_() {}
 
 augment C2 topLevelFunction3(C1 a, ) {
@@ -55,7 +57,6 @@
 external C2 topLevelFunction3(C1 a);
 
 /*member: topLevelFunction4:
-
 void topLevelFunction4GeneratedMethod_() {}
 
 augment D2 topLevelFunction4(D1 a, ) {
diff --git a/pkg/front_end/test/macro_application/data/tests/subtypes.dart.expect b/pkg/front_end/test/macro_application/data/tests/subtypes.dart.expect
new file mode 100644
index 0000000..d428183
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/subtypes.dart.expect
@@ -0,0 +1,59 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:macro/macro.dart" as mac;
+
+import "package:macro/macro.dart";
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B1 extends core::Object {
+  synthetic constructor •() → self::B1
+    : super core::Object::•()
+    ;
+}
+class B2 extends self::B1 {
+  synthetic constructor •() → self::B2
+    : super self::B1::•()
+    ;
+}
+class C1 extends self::C2 {
+  synthetic constructor •() → self::C1
+    : super self::C2::•()
+    ;
+}
+class C2 extends core::Object {
+  synthetic constructor •() → self::C2
+    : super core::Object::•()
+    ;
+}
+class D1 extends core::Object {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+}
+class D2 extends core::Object {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+}
+@#C1
+@#C2
+external static method topLevelFunction1(self::A a) → self::A;
+@#C1
+@#C2
+external static method topLevelFunction2(self::B1 a) → self::B2;
+@#C1
+@#C2
+external static method topLevelFunction3(self::C1 a) → self::C2;
+@#C1
+@#C2
+external static method topLevelFunction4(self::D1 a) → self::D2;
+
+constants  {
+  #C1 = mac::FunctionDeclarationsMacro2 {}
+  #C2 = mac::FunctionDefinitionMacro2 {}
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/type_annotations.dart b/pkg/front_end/test/macro_application/data/tests/type_annotations.dart
index 35867d9..dfee364 100644
--- a/pkg/front_end/test/macro_application/data/tests/type_annotations.dart
+++ b/pkg/front_end/test/macro_application/data/tests/type_annotations.dart
@@ -2,12 +2,16 @@
 // 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.
 
+/*library: 
+
+
+*/
+
 import 'dart:math' as math;
 
 import 'package:macro/macro.dart';
 
 /*member: topLevelFunction1:
-
 augment void topLevelFunction1() {
   return 42;
 }*/
@@ -15,7 +19,6 @@
 external void topLevelFunction1();
 
 /*member: topLevelFunction2:
-
 augment dynamic topLevelFunction2() {
   return 42;
 }*/
@@ -23,7 +26,6 @@
 external dynamic topLevelFunction2();
 
 /*member: topLevelFunction3:
-
 augment int topLevelFunction3() {
   return 42;
 }*/
@@ -31,7 +33,6 @@
 external int topLevelFunction3();
 
 /*member: topLevelFunction4:
-
 augment dynamic topLevelFunction4() {
   return 42;
 }*/
@@ -39,7 +40,6 @@
 external topLevelFunction4();
 
 /*member: topLevelFunction5:
-
 augment math.Random topLevelFunction5() {
   return 42;
 }*/
@@ -47,7 +47,6 @@
 external math.Random topLevelFunction5();
 
 /*member: topLevelFunction6:
-
 augment List<int> topLevelFunction6() {
   return 42;
 }*/
@@ -55,7 +54,6 @@
 external List<int> topLevelFunction6();
 
 /*member: topLevelFunction7:
-
 augment Map<math.Random, List<int>> topLevelFunction7() {
   return 42;
 }*/
@@ -63,7 +61,6 @@
 external Map<math.Random, List<int>> topLevelFunction7();
 
 /*member: topLevelFunction8:
-
 augment Map<int?, String>? topLevelFunction8() {
   return 42;
 }*/
diff --git a/pkg/front_end/test/macro_application/data/tests/type_annotations.dart.expect b/pkg/front_end/test/macro_application/data/tests/type_annotations.dart.expect
new file mode 100644
index 0000000..219150c
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/type_annotations.dart.expect
@@ -0,0 +1,29 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "package:macro/macro.dart" as mac;
+import "dart:core" as core;
+import "dart:math" as math;
+
+import "dart:math" as math;
+import "package:macro/macro.dart";
+
+@#C1
+external static method topLevelFunction1() → void;
+@#C1
+external static method topLevelFunction2() → dynamic;
+@#C1
+external static method topLevelFunction3() → core::int;
+@#C1
+external static method topLevelFunction4() → dynamic;
+@#C1
+external static method topLevelFunction5() → math::Random;
+@#C1
+external static method topLevelFunction6() → core::List<core::int>;
+@#C1
+external static method topLevelFunction7() → core::Map<math::Random, core::List<core::int>>;
+@#C1
+external static method topLevelFunction8() → core::Map<core::int?, core::String>?;
+
+constants  {
+  #C1 = mac::FunctionDefinitionMacro1 {}
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/types.dart b/pkg/front_end/test/macro_application/data/tests/types.dart
index 2dbb05d..883e037 100644
--- a/pkg/front_end/test/macro_application/data/tests/types.dart
+++ b/pkg/front_end/test/macro_application/data/tests/types.dart
@@ -2,35 +2,61 @@
 // 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.
 
+/*library: 
+import 'dart:core' as i0;
+import 'package:macro/macro.dart' as i1;
+
+
+class topLevelFunction1GeneratedClass {
+  external void method();
+}
+class topLevelFunction2GeneratedClass {
+  external i0.dynamic method();
+}
+class topLevelFunction3GeneratedClass {
+  external i0.int method();
+}
+class topLevelFunction4GeneratedClass {
+  external i1.FunctionTypesMacro1? method();
+}
+class topLevelFunction5GeneratedClass {
+  external i0.dynamic method();
+}
+*/
+
 import 'package:macro/macro.dart';
 
 /*member: topLevelFunction1:
-class topLevelFunction1GeneratedClass<T extends void> {}*/
+class topLevelFunction1GeneratedClass {
+  external void method();
+}*/
 @FunctionTypesMacro1()
 void topLevelFunction1() {}
 
 /*member: topLevelFunction2:
-class topLevelFunction2GeneratedClass<T extends dynamic> {}*/
+class topLevelFunction2GeneratedClass {
+  external dynamic method();
+}*/
 @FunctionTypesMacro1()
 dynamic topLevelFunction2() {}
 
 /*member: topLevelFunction3:
-import 'dart:core' as i0;
-
-
-class topLevelFunction3GeneratedClass<T extends i0.int> {}*/
+class topLevelFunction3GeneratedClass {
+  external int method();
+}*/
 @FunctionTypesMacro1()
 int topLevelFunction3() => 0;
 
 /*member: topLevelFunction4:
-import 'package:macro/macro.dart' as i0;
-
-
-class topLevelFunction4GeneratedClass<T extends i0.FunctionTypesMacro1?> {}*/
+class topLevelFunction4GeneratedClass {
+  external FunctionTypesMacro1? method();
+}*/
 @FunctionTypesMacro1()
 FunctionTypesMacro1? topLevelFunction4() => null;
 
 /*member: topLevelFunction5:
-class topLevelFunction5GeneratedClass<T extends dynamic> {}*/
+class topLevelFunction5GeneratedClass {
+  external dynamic method();
+}*/
 @FunctionTypesMacro1()
 topLevelFunction5() {}
diff --git a/pkg/front_end/test/macro_application/data/tests/types.dart.expect b/pkg/front_end/test/macro_application/data/tests/types.dart.expect
new file mode 100644
index 0000000..e36ef4f
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/types.dart.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:macro/macro.dart" as mac;
+
+import "dart:core" as i0;
+import "package:macro/macro.dart" as i1;
+import "package:macro/macro.dart";
+
+class topLevelFunction1GeneratedClass extends core::Object { // from org-dartlang-augmentation:/a/b/c/main.dart-0
+  synthetic constructor •() → self::topLevelFunction1GeneratedClass
+    : super core::Object::•()
+    ;
+  external method method() → void;
+}
+class topLevelFunction2GeneratedClass extends core::Object { // from org-dartlang-augmentation:/a/b/c/main.dart-0
+  synthetic constructor •() → self::topLevelFunction2GeneratedClass
+    : super core::Object::•()
+    ;
+  external method method() → dynamic;
+}
+class topLevelFunction3GeneratedClass extends core::Object { // from org-dartlang-augmentation:/a/b/c/main.dart-0
+  synthetic constructor •() → self::topLevelFunction3GeneratedClass
+    : super core::Object::•()
+    ;
+  external method method() → core::int;
+}
+class topLevelFunction4GeneratedClass extends core::Object { // from org-dartlang-augmentation:/a/b/c/main.dart-0
+  synthetic constructor •() → self::topLevelFunction4GeneratedClass
+    : super core::Object::•()
+    ;
+  external method method() → mac::FunctionTypesMacro1?;
+}
+class topLevelFunction5GeneratedClass extends core::Object { // from org-dartlang-augmentation:/a/b/c/main.dart-0
+  synthetic constructor •() → self::topLevelFunction5GeneratedClass
+    : super core::Object::•()
+    ;
+  external method method() → dynamic;
+}
+@#C1
+static method topLevelFunction1() → void {}
+@#C1
+static method topLevelFunction2() → dynamic {}
+@#C1
+static method topLevelFunction3() → core::int
+  return 0;
+@#C1
+static method topLevelFunction4() → mac::FunctionTypesMacro1?
+  return null;
+@#C1
+static method topLevelFunction5() → dynamic {}
+
+constants  {
+  #C1 = mac::FunctionTypesMacro1 {}
+}
diff --git a/pkg/front_end/test/macro_application/macro_application_test.dart b/pkg/front_end/test/macro_application/macro_application_test.dart
index 18e8fdf..9282bac 100644
--- a/pkg/front_end/test/macro_application/macro_application_test.dart
+++ b/pkg/front_end/test/macro_application/macro_application_test.dart
@@ -2,7 +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:io' show Directory, Platform;
+import 'dart:io' show Directory, File, Platform;
 
 import 'package:_fe_analyzer_shared/src/macros/api.dart';
 import 'package:_fe_analyzer_shared/src/macros/executor.dart';
@@ -10,7 +10,7 @@
 import 'package:_fe_analyzer_shared/src/macros/isolated_executor/isolated_executor.dart'
     as isolatedExecutor;
 import 'package:_fe_analyzer_shared/src/testing/id.dart'
-    show ActualData, ClassId, Id;
+    show ActualData, ClassId, Id, LibraryId;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
@@ -19,14 +19,20 @@
 import 'package:front_end/src/fasta/kernel/macro.dart';
 import 'package:front_end/src/fasta/kernel/utils.dart';
 import 'package:front_end/src/fasta/source/source_class_builder.dart';
+import 'package:front_end/src/fasta/source/source_library_builder.dart';
+import 'package:front_end/src/testing/compiler_common.dart';
 import 'package:front_end/src/testing/id_extractor.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:kernel/ast.dart' hide Arguments;
 import 'package:kernel/kernel.dart';
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/text/ast_to_text.dart';
 import 'package:vm/target/vm.dart';
 
+import '../utils/kernel_chain.dart';
+
 Future<void> main(List<String> args) async {
+  bool generateExpectations = args.contains('-g');
   enableMacros = true;
 
   Directory tempDirectory =
@@ -38,8 +44,10 @@
         args: args,
         createUriForFileName: createUriForFileName,
         onFailure: onFailure,
-        runTest: runTestFor(
-            const MacroDataComputer(), [new MacroTestConfig(tempDirectory)]),
+        runTest: runTestFor(const MacroDataComputer(), [
+          new MacroTestConfig(dataDir, tempDirectory,
+              generateExpectations: generateExpectations)
+        ]),
         preserveWhitespaceInAnnotations: true);
   } finally {
     await tempDirectory.delete(recursive: true);
@@ -47,11 +55,14 @@
 }
 
 class MacroTestConfig extends TestConfig {
+  final Directory dataDir;
   final Directory tempDirectory;
+  final bool generateExpectations;
   int precompiledCount = 0;
   final Map<MacroClass, Uri> precompiledMacroUris = {};
 
-  MacroTestConfig(this.tempDirectory)
+  MacroTestConfig(this.dataDir, this.tempDirectory,
+      {required this.generateExpectations})
       : super(cfeMarker, 'cfe',
             explicitExperimentalFlags: {ExperimentalFlag.macros: true},
             packageConfigUri:
@@ -71,6 +82,42 @@
       return uri;
     };
   }
+
+  @override
+  Future<void> onCompilationResult(
+      TestData testData, TestResultData testResultData) async {
+    Component component = testResultData.compilerResult.component!;
+    StringBuffer buffer = new StringBuffer();
+    Printer printer = new Printer(buffer)
+      ..writeProblemsAsJson("Problems in component", component.problemsAsJson);
+    component.libraries.forEach((Library library) {
+      if (isTestUri(library.importUri)) {
+        printer.writeLibraryFile(library);
+        printer.endLine();
+      }
+    });
+    printer.writeConstantTable(component);
+    String actual = buffer.toString();
+    String expectationFileName = '${testData.name}.expect';
+    Uri expectedUri = dataDir.uri.resolve(expectationFileName);
+    File file = new File.fromUri(expectedUri);
+    if (file.existsSync()) {
+      String expected = file.readAsStringSync();
+      if (expected != actual) {
+        if (generateExpectations) {
+          file.writeAsStringSync(actual);
+        } else {
+          String diff = await runDiff(expectedUri, actual);
+          throw "${testData.name} don't match ${expectedUri}\n$diff";
+        }
+      }
+    } else if (generateExpectations) {
+      file.writeAsStringSync(actual);
+    } else {
+      throw 'Please use -g option to create file ${expectedUri} with this '
+          'content:\n$actual';
+    }
+  }
 }
 
 bool _isMember(MemberBuilder memberBuilder, Member member) {
@@ -93,6 +140,34 @@
   DataInterpreter<String> get dataValidator => const StringDataInterpreter();
 
   @override
+  void computeLibraryData(TestResultData testResultData, Library library,
+      Map<Id, ActualData<String>> actualMap,
+      {bool? verbose}) {
+    CfeDataRegistry<String> registry =
+        new CfeDataRegistry(testResultData.compilerResult, actualMap);
+    MacroApplicationDataForTesting macroApplicationData = testResultData
+        .compilerResult
+        .kernelTargetForTesting!
+        .loader
+        .dataForTesting!
+        .macroApplicationData;
+    StringBuffer sb = new StringBuffer();
+    for (SourceLibraryBuilder sourceLibraryBuilder
+        in macroApplicationData.libraryTypesResult.keys) {
+      if (sourceLibraryBuilder.library == library) {
+        String source =
+            macroApplicationData.libraryTypesResult[sourceLibraryBuilder]!;
+        sb.write('\n${source}');
+      }
+    }
+    if (sb.isNotEmpty) {
+      Id id = new LibraryId(library.fileUri);
+      registry.registerValue(
+          library.fileUri, library.fileOffset, id, sb.toString(), library);
+    }
+  }
+
+  @override
   void computeClassData(TestResultData testResultData, Class cls,
       Map<Id, ActualData<String>> actualMap,
       {bool? verbose}) {
@@ -105,10 +180,12 @@
         .dataForTesting!
         .macroApplicationData;
     StringBuffer sb = new StringBuffer();
-    for (MapEntry<SourceClassBuilder, String> entry
+    for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
         in macroApplicationData.classTypesResults.entries) {
       if (entry.key.cls == cls) {
-        sb.write('\n${entry.value.trim()}');
+        for (MacroExecutionResult result in entry.value) {
+          sb.write('\n${codeToString(result.augmentations.first)}');
+        }
       }
     }
     for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
@@ -147,10 +224,12 @@
         .dataForTesting!
         .macroApplicationData;
     StringBuffer sb = new StringBuffer();
-    for (MapEntry<MemberBuilder, String> entry
+    for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
         in macroApplicationData.memberTypesResults.entries) {
       if (_isMember(entry.key, member)) {
-        sb.write('\n${entry.value.trim()}');
+        for (MacroExecutionResult result in entry.value) {
+          sb.write('\n${codeToString(result.augmentations.first)}');
+        }
       }
     }
     for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index bac7ac7..9284ec3 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -624,6 +624,7 @@
   static const none = Compiler._('none');
   static const dart2js = Compiler._('dart2js');
   static const dart2analyzer = Compiler._('dart2analyzer');
+  static const dart2wasm = Compiler._('dart2wasm');
   static const compareAnalyzerCfe = Compiler._('compare_analyzer_cfe');
   static const dartdevc = Compiler._('dartdevc');
   static const dartdevk = Compiler._('dartdevk');
@@ -639,6 +640,7 @@
     none,
     dart2js,
     dart2analyzer,
+    dart2wasm,
     compareAnalyzerCfe,
     dartdevc,
     dartdevk,
@@ -691,6 +693,12 @@
           Runtime.safari,
         ];
 
+      case Compiler.dart2wasm:
+        return const [
+          Runtime.none,
+          Runtime.d8,
+          Runtime.chrome,
+        ];
       case Compiler.dart2analyzer:
       case Compiler.compareAnalyzerCfe:
         return const [Runtime.none];
@@ -716,6 +724,8 @@
     switch (this) {
       case Compiler.dart2js:
         return Runtime.d8;
+      case Compiler.dart2wasm:
+        return Runtime.d8;
       case Compiler.dartdevc:
       case Compiler.dartdevk:
         return Runtime.chrome;
@@ -742,6 +752,7 @@
       case Compiler.dart2analyzer:
       case Compiler.compareAnalyzerCfe:
       case Compiler.dart2js:
+      case Compiler.dart2wasm:
       case Compiler.dartdevc:
       case Compiler.dartdevk:
       case Compiler.fasta:
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index 45fa5d2..7ba599f 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -186,6 +186,9 @@
     if (displayName == 'precompiler' || displayName == 'app_jit') {
       return VMCommandOutput(
           this, exitCode, timedOut, stdout, stderr, time, pid);
+    } else if (displayName == 'dart2wasm') {
+      return Dart2WasmCompilerCommandOutput(
+          this, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
     }
 
     return CompilationCommandOutput(
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index cc65097..03db24c 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -1060,6 +1060,45 @@
   }
 }
 
+class Dart2WasmCompilerCommandOutput extends CompilationCommandOutput
+    with _StaticErrorOutput {
+  static void parseErrors(String stdout, List<StaticError> errors) {
+    _StaticErrorOutput._parseCfeErrors(
+        ErrorSource.web, _errorRegexp, stdout, errors);
+  }
+
+  /// Matches the location and message of a dart2wasm error message, which looks
+  /// like:
+  ///
+  ///     tests/language_2/some_test.dart:9:3: Error: Some message.
+  ///       BadThing();
+  ///       ^
+  ///
+  /// The test runner only validates the main error message, and not the
+  /// suggested fixes, so we only parse the first line.
+  // TODO(rnystrom): Support validating context messages.
+  static final _errorRegexp =
+      RegExp(r"^([^:]+):(\d+):(\d+): (Error): (.*)$", multiLine: true);
+
+  Dart2WasmCompilerCommandOutput(
+      Command command,
+      int exitCode,
+      bool timedOut,
+      List<int> stdout,
+      List<int> stderr,
+      Duration time,
+      bool compilationSkipped)
+      : super(command, exitCode, timedOut, stdout, stderr, time,
+            compilationSkipped);
+
+  @override
+  void _parseErrors() {
+    var errors = <StaticError>[];
+    parseErrors(decodeUtf8(stdout), errors);
+    errors.forEach(addError);
+  }
+}
+
 class DevCompilerCommandOutput extends CommandOutput with _StaticErrorOutput {
   /// Matches the first line of a DDC error message. DDC prints errors to
   /// stdout that look like:
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 6d72e22..b287bcc 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -86,6 +86,9 @@
       case Compiler.dart2js:
         return Dart2jsCompilerConfiguration(configuration);
 
+      case Compiler.dart2wasm:
+        return Dart2WasmCompilerConfiguration(configuration);
+
       case Compiler.dartdevc:
         return DevCompilerConfiguration(configuration);
 
@@ -499,6 +502,83 @@
   }
 }
 
+/// Common configuration for dart2wasm-based tools, such as dart2wasm.
+class Dart2WasmCompilerConfiguration extends CompilerConfiguration {
+  Dart2WasmCompilerConfiguration(TestConfiguration configuration)
+      : super._subclass(configuration);
+
+  String computeCompilerPath() {
+    var prefix = 'sdk/bin';
+    if (_isHostChecked) {
+      if (_useSdk) {
+        throw "--host-checked and --use-sdk cannot be used together";
+      }
+      // The script dart2wasm_developer is not included in the
+      // shipped SDK, that is the script is not installed in
+      // "$buildDir/dart-sdk/bin/"
+      return '$prefix/dart2wasm_developer$shellScriptExtension';
+    }
+    if (_useSdk) {
+      prefix = '${_configuration.buildDirectory}/dart-sdk/bin';
+    }
+    return '$prefix/dart2wasm$shellScriptExtension';
+  }
+
+  List<String> computeCompilerArguments(
+      TestFile testFile, List<String> vmOptions, List<String> args) {
+    return [
+      // The file being compiled is the last argument.
+      args.last
+    ];
+  }
+
+  Command computeCompilationCommand(String outputFileName,
+      List<String> arguments, Map<String, String> environmentOverrides) {
+    arguments = arguments.toList();
+    arguments.add('$outputFileName');
+
+    return CompilationCommand(
+        'dart2wasm',
+        outputFileName,
+        bootstrapDependencies(),
+        computeCompilerPath(),
+        arguments,
+        environmentOverrides,
+        alwaysCompile: !_useSdk);
+  }
+
+  CommandArtifact computeCompilationArtifact(String tempDir,
+      List<String> arguments, Map<String, String> environmentOverrides) {
+    var compilerArguments = [
+      ...arguments,
+    ];
+
+    var inputFile = arguments.last;
+    var inputFilename = Uri.file(inputFile).pathSegments.last;
+    var out = "$tempDir/${inputFilename.replaceAll('.dart', '.wasm')}";
+    var commands = [
+      computeCompilationCommand(out, compilerArguments, environmentOverrides),
+    ];
+
+    return CommandArtifact(commands, out, 'application/wasm');
+  }
+
+  List<String> computeRuntimeArguments(
+      RuntimeConfiguration runtimeConfiguration,
+      TestFile testFile,
+      List<String> vmOptions,
+      List<String> originalArguments,
+      CommandArtifact artifact) {
+    return [
+      '--experimental-wasm-gc',
+      '--wasm-gc-js-interop',
+      'pkg/dart2wasm/bin/run_wasm.js',
+      '--',
+      artifact.filename,
+    ];
+  }
+}
+
 /// Configuration for `dartdevc` and `dartdevk` (DDC with Kernel)
 class DevCompilerConfiguration extends CompilerConfiguration {
   DevCompilerConfiguration(TestConfiguration configuration)
diff --git a/pkg/test_runner/lib/src/configuration.dart b/pkg/test_runner/lib/src/configuration.dart
index 198c01a..d98b8b8 100644
--- a/pkg/test_runner/lib/src/configuration.dart
+++ b/pkg/test_runner/lib/src/configuration.dart
@@ -203,6 +203,7 @@
       Compiler.dartkp,
       Compiler.fasta,
       Compiler.dart2js,
+      Compiler.dart2wasm,
     ];
     return fastaCompilers.contains(compiler);
   }
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 2341361..4cba518 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -168,7 +168,7 @@
 
   void checkArtifact(CommandArtifact artifact) {
     var type = artifact.mimeType;
-    if (type != 'application/javascript') {
+    if (type != 'application/javascript' && type != 'application/wasm') {
       throw "Runtime '$moniker' cannot run files of type '$type'.";
     }
   }
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index 5aeaf54..faf6d57 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -597,6 +597,7 @@
       '$directory/${name}_analyzer.status',
       '$directory/${name}_analyzer2.status',
       '$directory/${name}_dart2js.status',
+      '$directory/${name}_dart2wasm.status',
       '$directory/${name}_dartdevc.status',
       '$directory/${name}_kernel.status',
       '$directory/${name}_precompiled.status',
@@ -956,6 +957,7 @@
     var commands = <Command>[];
     const supportedCompilers = {
       Compiler.dart2js,
+      Compiler.dart2wasm,
       Compiler.dartdevc,
       Compiler.dartdevk
     };
diff --git a/pkg/wasm_builder/LICENSE b/pkg/wasm_builder/LICENSE
new file mode 100644
index 0000000..9566a27
--- /dev/null
+++ b/pkg/wasm_builder/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2022, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/wasm_builder/lib/src/instructions.dart b/pkg/wasm_builder/lib/src/instructions.dart
new file mode 100644
index 0000000..24a9556
--- /dev/null
+++ b/pkg/wasm_builder/lib/src/instructions.dart
@@ -0,0 +1,2283 @@
+// Copyright (c) 2022, 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 'module.dart';
+import 'serialize.dart';
+import 'types.dart';
+
+/// Thrown when Wasm bytecode validation fails.
+class ValidationError {
+  final String trace;
+  final String error;
+
+  ValidationError(this.trace, this.error);
+
+  @override
+  String toString() => "$trace\n$error";
+}
+
+/// Label to use as target for branch instructions.
+abstract class Label {
+  final List<ValueType> inputs;
+  final List<ValueType> outputs;
+
+  late final int? ordinal;
+  late final int depth;
+  late final int baseStackHeight;
+  late final bool reachable;
+
+  Label._(this.inputs, this.outputs);
+
+  List<ValueType> get targetTypes;
+
+  bool get hasOrdinal => ordinal != null;
+
+  @override
+  String toString() => "L$ordinal";
+}
+
+class Expression extends Label {
+  Expression(List<ValueType> inputs, List<ValueType> outputs)
+      : super._(inputs, outputs) {
+    ordinal = null;
+    depth = 0;
+    baseStackHeight = 0;
+    reachable = true;
+  }
+
+  List<ValueType> get targetTypes => outputs;
+}
+
+class Block extends Label {
+  Block(List<ValueType> inputs, List<ValueType> outputs)
+      : super._(inputs, outputs);
+
+  List<ValueType> get targetTypes => outputs;
+}
+
+class Loop extends Label {
+  Loop(List<ValueType> inputs, List<ValueType> outputs)
+      : super._(inputs, outputs);
+
+  List<ValueType> get targetTypes => inputs;
+}
+
+class If extends Label {
+  bool hasElse = false;
+
+  If(List<ValueType> inputs, List<ValueType> outputs)
+      : super._(inputs, outputs);
+
+  List<ValueType> get targetTypes => outputs;
+}
+
+/// A sequence of Wasm instructions.
+///
+/// Instructions can be added to the sequence by calling the corresponding
+/// instruction methods.
+///
+/// If asserts are enabled, the instruction methods will perform on-the-fly
+/// validation and throw a [ValidationError] if validation fails.
+class Instructions with SerializerMixin {
+  /// The module containing these instructions.
+  final Module module;
+
+  /// Locals declared in this body, including parameters.
+  final List<Local> locals;
+
+  /// Is this the initializer of a global variable?
+  final bool isGlobalInitializer;
+
+  /// Whether a textual trace of the instruction stream should be recorded when
+  /// emitting instructions (provided asserts are enabled).
+  ///
+  /// This trace can be accessed via the [trace] property and will be part of
+  /// the exception text if a validation error occurs.
+  bool traceEnabled = true;
+
+  /// Whether to print a byte offset for each instruction in the textual trace.
+  bool byteOffsetEnabled = false;
+
+  /// Column width for the instruction byte offset.
+  int byteOffsetWidth = 7;
+
+  /// Column width for the instructions.
+  int instructionColumnWidth = 50;
+
+  int _indent = 1;
+  final List<String> _traceLines = [];
+
+  int _labelCount = 0;
+  final List<Label> _labelStack = [];
+  final List<ValueType> _stackTypes = [];
+  bool _reachable = true;
+
+  /// Create a new instruction sequence.
+  Instructions(this.module, List<ValueType> outputs,
+      {this.locals = const [], this.isGlobalInitializer = false}) {
+    _labelStack.add(Expression(const [], outputs));
+  }
+
+  /// Whether the current point in the instruction stream is reachable.
+  bool get reachable => _reachable;
+
+  /// Whether the instruction sequence has been completed by the final `end`.
+  bool get isComplete => _labelStack.isEmpty;
+
+  /// Textual trace of the instructions.
+  String get trace => _traceLines.join();
+
+  bool _debugTrace(List<Object>? trace,
+      {required bool reachableAfter,
+      int indentBefore = 0,
+      int indentAfter = 0}) {
+    if (traceEnabled && trace != null) {
+      _indent += indentBefore;
+      String byteOffset =
+          byteOffsetEnabled ? "${data.length}".padLeft(byteOffsetWidth) : "";
+      String instr = "  " * _indent + " " + trace.join(" ");
+      instr = instr.length > instructionColumnWidth - 2
+          ? instr.substring(0, instructionColumnWidth - 4) + "... "
+          : instr.padRight(instructionColumnWidth);
+      final String stack = reachableAfter ? _stackTypes.join(', ') : "-";
+      final String line = "$byteOffset$instr$stack\n";
+      _indent += indentAfter;
+
+      _traceLines.add(line);
+    }
+    return true;
+  }
+
+  bool _comment(String text) {
+    if (traceEnabled) {
+      final String line = " " * (byteOffsetEnabled ? byteOffsetWidth : 0) +
+          "  " * _indent +
+          " ;; $text\n";
+      _traceLines.add(line);
+    }
+    return true;
+  }
+
+  Never _reportError(String error) {
+    throw ValidationError(trace, error);
+  }
+
+  ValueType get _topOfStack {
+    if (!reachable) return RefType.any();
+    if (_stackTypes.isEmpty) _reportError("Stack underflow");
+    return _stackTypes.last;
+  }
+
+  Label get _topOfLabelStack {
+    if (_labelStack.isEmpty) _reportError("Label stack underflow");
+    return _labelStack.last;
+  }
+
+  List<ValueType> _stack(int n) {
+    if (_stackTypes.length < n) _reportError("Stack underflow");
+    return _stackTypes.sublist(_stackTypes.length - n);
+  }
+
+  List<ValueType> _checkStackTypes(List<ValueType> inputs,
+      [List<ValueType>? stack]) {
+    stack ??= _stack(inputs.length);
+    bool typesMatch = true;
+    for (int i = 0; i < inputs.length; i++) {
+      if (!stack[i].isSubtypeOf(inputs[i])) {
+        typesMatch = false;
+        break;
+      }
+    }
+    if (!typesMatch) {
+      final String expected = inputs.join(', ');
+      final String got = stack.join(', ');
+      _reportError("Expected [$expected], but stack contained [$got]");
+    }
+    return stack;
+  }
+
+  bool _verifyTypes(List<ValueType> inputs, List<ValueType> outputs,
+      {List<Object>? trace, bool reachableAfter = true}) {
+    return _verifyTypesFun(inputs, (_) => outputs,
+        trace: trace, reachableAfter: reachableAfter);
+  }
+
+  bool _verifyTypesFun(List<ValueType> inputs,
+      List<ValueType> Function(List<ValueType>) outputsFun,
+      {List<Object>? trace, bool reachableAfter = true}) {
+    if (!reachable) {
+      return _debugTrace(trace, reachableAfter: false);
+    }
+    if (_stackTypes.length - inputs.length < _topOfLabelStack.baseStackHeight) {
+      _reportError("Underflowing base stack of innermost block");
+    }
+    final List<ValueType> stack = _checkStackTypes(inputs);
+    _stackTypes.length -= inputs.length;
+    _stackTypes.addAll(outputsFun(stack));
+    return _debugTrace(trace, reachableAfter: reachableAfter);
+  }
+
+  bool _verifyBranchTypes(Label label,
+      [int popped = 0, List<ValueType> pushed = const []]) {
+    if (!reachable) {
+      return true;
+    }
+    final List<ValueType> inputs = label.targetTypes;
+    if (_stackTypes.length - popped + pushed.length - inputs.length <
+        label.baseStackHeight) {
+      _reportError("Underflowing base stack of target label");
+    }
+    final List<ValueType> stack = inputs.length <= pushed.length
+        ? pushed.sublist(pushed.length - inputs.length)
+        : [
+            ..._stackTypes.sublist(
+                _stackTypes.length - popped + pushed.length - inputs.length,
+                _stackTypes.length - popped),
+            ...pushed
+          ];
+    _checkStackTypes(inputs, stack);
+    return true;
+  }
+
+  bool _verifyStartOfBlock(Label label, {required List<Object> trace}) {
+    return _debugTrace(
+        ["$label:", ...trace, FunctionType(label.inputs, label.outputs)],
+        reachableAfter: reachable, indentAfter: 1);
+  }
+
+  bool _verifyEndOfBlock(List<ValueType> outputs,
+      {required List<Object> trace,
+      required bool reachableAfter,
+      required bool reindent}) {
+    final Label label = _topOfLabelStack;
+    if (reachable) {
+      final int expectedHeight = label.baseStackHeight + label.outputs.length;
+      if (_stackTypes.length != expectedHeight) {
+        _reportError("Incorrect stack height at end of block"
+            " (expected $expectedHeight, actual ${_stackTypes.length})");
+      }
+      _checkStackTypes(label.outputs);
+    }
+    if (label.reachable) {
+      assert(_stackTypes.length >= label.baseStackHeight);
+      _stackTypes.length = label.baseStackHeight;
+      _stackTypes.addAll(outputs);
+    }
+    return _debugTrace([if (label.hasOrdinal) "$label:", ...trace],
+        reachableAfter: reachableAfter,
+        indentBefore: -1,
+        indentAfter: reindent ? 1 : 0);
+  }
+
+  // Meta
+
+  /// Emit a comment.
+  void comment(String text) {
+    assert(_comment(text));
+  }
+
+  // Control instructions
+
+  /// Emit an `unreachable` instruction.
+  void unreachable() {
+    assert(_verifyTypes(const [], const [],
+        trace: const ['unreachable'], reachableAfter: false));
+    _reachable = false;
+    writeByte(0x00);
+  }
+
+  /// Emit a `nop` instruction.
+  void nop() {
+    assert(_verifyTypes(const [], const [], trace: const ['nop']));
+    writeByte(0x01);
+  }
+
+  Label _beginBlock(int encoding, Label label, {required List<Object> trace}) {
+    assert(_verifyTypes(label.inputs, label.inputs));
+    label.ordinal = ++_labelCount;
+    label.depth = _labelStack.length;
+    label.baseStackHeight = _stackTypes.length - label.inputs.length;
+    label.reachable = reachable;
+    _labelStack.add(label);
+    assert(_verifyStartOfBlock(label, trace: trace));
+    writeByte(encoding);
+    if (label.inputs.isEmpty && label.outputs.isEmpty) {
+      writeByte(0x40);
+    } else if (label.inputs.isEmpty && label.outputs.length == 1) {
+      write(label.outputs.single);
+    } else {
+      final type = module.addFunctionType(label.inputs, label.outputs);
+      writeSigned(type.index);
+    }
+    return label;
+  }
+
+  /// Emit a `block` instruction.
+  /// Branching to the returned label will branch to the matching `end`.
+  Label block(
+      [List<ValueType> inputs = const [], List<ValueType> outputs = const []]) {
+    return _beginBlock(0x02, Block(inputs, outputs), trace: const ['block']);
+  }
+
+  /// Emit a `loop` instruction.
+  /// Branching to the returned label will branch to the `loop`.
+  Label loop(
+      [List<ValueType> inputs = const [], List<ValueType> outputs = const []]) {
+    return _beginBlock(0x03, Loop(inputs, outputs), trace: const ['loop']);
+  }
+
+  /// Emit an `if` instruction.
+  /// Branching to the returned label will branch to the matching `end`.
+  Label if_(
+      [List<ValueType> inputs = const [], List<ValueType> outputs = const []]) {
+    assert(_verifyTypes(const [NumType.i32], const []));
+    return _beginBlock(0x04, If(inputs, outputs), trace: const ['if']);
+  }
+
+  /// Emit an `else` instruction.
+  void else_() {
+    assert(_topOfLabelStack is If ||
+        _reportError("Unexpected 'else' (not in 'if' block)"));
+    final If label = _topOfLabelStack as If;
+    assert(!label.hasElse || _reportError("Duplicate 'else' in 'if' block"));
+    assert(_verifyEndOfBlock(label.inputs,
+        trace: const ['else'],
+        reachableAfter: _topOfLabelStack.reachable,
+        reindent: true));
+    label.hasElse = true;
+    _reachable = _topOfLabelStack.reachable;
+    writeByte(0x05);
+  }
+
+  /// Emit an `end` instruction.
+  void end() {
+    assert(_verifyEndOfBlock(_topOfLabelStack.outputs,
+        trace: const ['end'],
+        reachableAfter: _topOfLabelStack.reachable,
+        reindent: false));
+    _reachable = _topOfLabelStack.reachable;
+    _labelStack.removeLast();
+    writeByte(0x0B);
+  }
+
+  int _labelIndex(Label label) {
+    final int index = _labelStack.length - label.depth - 1;
+    assert(_labelStack[label.depth] == label);
+    return index;
+  }
+
+  void _writeLabel(Label label) {
+    writeUnsigned(_labelIndex(label));
+  }
+
+  /// Emit a `br` instruction.
+  void br(Label label) {
+    assert(_verifyTypes(const [], const [],
+        trace: ['br', label], reachableAfter: false));
+    assert(_verifyBranchTypes(label));
+    _reachable = false;
+    writeByte(0x0C);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_if` instruction.
+  void br_if(Label label) {
+    assert(
+        _verifyTypes(const [NumType.i32], const [], trace: ['br_if', label]));
+    assert(_verifyBranchTypes(label));
+    writeByte(0x0D);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_table` instruction.
+  void br_table(List<Label> labels, Label defaultLabel) {
+    assert(_verifyTypes(const [NumType.i32], const [],
+        trace: ['br_table', ...labels, defaultLabel], reachableAfter: false));
+    for (var label in labels) {
+      assert(_verifyBranchTypes(label));
+    }
+    assert(_verifyBranchTypes(defaultLabel));
+    _reachable = false;
+    writeByte(0x0E);
+    writeUnsigned(labels.length);
+    for (Label label in labels) {
+      _writeLabel(label);
+    }
+    _writeLabel(defaultLabel);
+  }
+
+  /// Emit a `return` instruction.
+  void return_() {
+    assert(_verifyTypes(_labelStack[0].outputs, const [],
+        trace: const ['return'], reachableAfter: false));
+    _reachable = false;
+    writeByte(0x0F);
+  }
+
+  /// Emit a `call` instruction.
+  void call(BaseFunction function) {
+    assert(_verifyTypes(function.type.inputs, function.type.outputs,
+        trace: ['call', function]));
+    writeByte(0x10);
+    writeUnsigned(function.index);
+  }
+
+  /// Emit a `call_indirect` instruction.
+  void call_indirect(FunctionType type, [Table? table]) {
+    assert(_verifyTypes([...type.inputs, NumType.i32], type.outputs,
+        trace: ['call_indirect', type, if (table != null) table.index]));
+    writeByte(0x11);
+    writeUnsigned(type.index);
+    writeUnsigned(table?.index ?? 0);
+  }
+
+  bool _verifyCallRef() {
+    if (!reachable) {
+      return _debugTrace(const ['call_ref'], reachableAfter: false);
+    }
+    ValueType fun = _topOfStack;
+    if (fun is RefType) {
+      var heapType = fun.heapType;
+      if (heapType is FunctionType) {
+        return _verifyTypes([...heapType.inputs, fun], heapType.outputs,
+            trace: const ['call_ref']);
+      }
+    }
+    _reportError("Expected function type, got $fun");
+  }
+
+  /// Emit a `call_ref` instruction.
+  void call_ref() {
+    assert(_verifyCallRef());
+    writeByte(0x14);
+  }
+
+  // Parametric instructions
+
+  /// Emit a `drop` instruction.
+  void drop() {
+    assert(_verifyTypes([_topOfStack], const [], trace: const ['drop']));
+    writeByte(0x1A);
+  }
+
+  /// Emit a `select` instruction.
+  void select(ValueType type) {
+    assert(_verifyTypes([type, type, NumType.i32], [type],
+        trace: ['select', type]));
+    if (type is NumType) {
+      writeByte(0x1B);
+    } else {
+      writeByte(0x1C);
+      writeUnsigned(1);
+      write(type);
+    }
+  }
+
+  // Variable instructions
+
+  /// Emit a `local.get` instruction.
+  void local_get(Local local) {
+    assert(locals[local.index] == local);
+    assert(_verifyTypes(const [], [local.type], trace: ['local.get', local]));
+    writeByte(0x20);
+    writeUnsigned(local.index);
+  }
+
+  /// Emit a `local.set` instruction.
+  void local_set(Local local) {
+    assert(locals[local.index] == local);
+    assert(_verifyTypes([local.type], const [], trace: ['local.set', local]));
+    writeByte(0x21);
+    writeUnsigned(local.index);
+  }
+
+  /// Emit a `local.tee` instruction.
+  void local_tee(Local local) {
+    assert(locals[local.index] == local);
+    assert(
+        _verifyTypes([local.type], [local.type], trace: ['local.tee', local]));
+    writeByte(0x22);
+    writeUnsigned(local.index);
+  }
+
+  /// Emit a `global.get` instruction.
+  void global_get(Global global) {
+    assert(_verifyTypes(const [], [global.type.type],
+        trace: ['global.get', global]));
+    writeByte(0x23);
+    writeUnsigned(global.index);
+  }
+
+  /// Emit a `global.set` instruction.
+  void global_set(Global global) {
+    assert(global.type.mutable);
+    assert(_verifyTypes([global.type.type], const [],
+        trace: ['global.set', global]));
+    writeByte(0x24);
+    writeUnsigned(global.index);
+  }
+
+  // Memory instructions
+
+  void _writeMemArg(Memory memory, int offset, int align) {
+    assert(align >= 0 && align < 64);
+    if (memory.index == 0) {
+      writeByte(align);
+      writeUnsigned(offset);
+    } else {
+      writeByte(64 + align);
+      writeUnsigned(offset);
+      writeUnsigned(memory.index);
+    }
+  }
+
+  /// Emit an `i32.load` instruction.
+  void i32_load(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: ['i32.load', memory.index, offset, align]));
+    writeByte(0x28);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load` instruction.
+  void i64_load(Memory memory, int offset, [int align = 3]) {
+    assert(align >= 0 && align <= 3);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load', memory.index, offset, align]));
+    writeByte(0x29);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `f32.load` instruction.
+  void f32_load(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f32],
+        trace: ['f32.load', memory.index, offset, align]));
+    writeByte(0x2A);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `f64.load` instruction.
+  void f64_load(Memory memory, int offset, [int align = 3]) {
+    assert(align >= 0 && align <= 3);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f64],
+        trace: ['f64.load', memory.index, offset, align]));
+    writeByte(0x2B);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.load8_s` instruction.
+  void i32_load8_s(Memory memory, int offset, [int align = 0]) {
+    assert(align == 0);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: ['i32.load8_s', memory.index, offset, align]));
+    writeByte(0x2C);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.load8_u` instruction.
+  void i32_load8_u(Memory memory, int offset, [int align = 0]) {
+    assert(align == 0);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: ['i32.load8_u', memory.index, offset, align]));
+    writeByte(0x2D);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.load16_s` instruction.
+  void i32_load16_s(Memory memory, int offset, [int align = 1]) {
+    assert(align >= 0 && align <= 1);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: ['i32.load16_s', memory.index, offset, align]));
+    writeByte(0x2E);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.load16_u` instruction.
+  void i32_load16_u(Memory memory, int offset, [int align = 1]) {
+    assert(align >= 0 && align <= 1);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: ['i32.load16_u', memory.index, offset, align]));
+    writeByte(0x2F);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load8_s` instruction.
+  void i64_load8_s(Memory memory, int offset, [int align = 0]) {
+    assert(align == 0);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load8_s', memory.index, offset, align]));
+    writeByte(0x30);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load8_u` instruction.
+  void i64_load8_u(Memory memory, int offset, [int align = 0]) {
+    assert(align == 0);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load8_u', memory.index, offset, align]));
+    writeByte(0x31);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load16_s` instruction.
+  void i64_load16_s(Memory memory, int offset, [int align = 1]) {
+    assert(align >= 0 && align <= 1);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load16_s', memory.index, offset, align]));
+    writeByte(0x32);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load16_u` instruction.
+  void i64_load16_u(Memory memory, int offset, [int align = 1]) {
+    assert(align >= 0 && align <= 1);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load16_u', memory.index, offset, align]));
+    writeByte(0x33);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load32_s` instruction.
+  void i64_load32_s(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load32_s', memory.index, offset, align]));
+    writeByte(0x34);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.load32_u` instruction.
+  void i64_load32_u(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: ['i64.load32_u', memory.index, offset, align]));
+    writeByte(0x35);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.store` instruction.
+  void i32_store(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [],
+        trace: ['i32.store', memory.index, offset, align]));
+    writeByte(0x36);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.store` instruction.
+  void i64_store(Memory memory, int offset, [int align = 3]) {
+    assert(align >= 0 && align <= 3);
+    assert(_verifyTypes(const [NumType.i32, NumType.i64], const [],
+        trace: ['i64.store', memory.index, offset, align]));
+    writeByte(0x37);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `f32.store` instruction.
+  void f32_store(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32, NumType.f32], const [],
+        trace: ['f32.store', memory.index, offset, align]));
+    writeByte(0x38);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `f64.store` instruction.
+  void f64_store(Memory memory, int offset, [int align = 3]) {
+    assert(align >= 0 && align <= 3);
+    assert(_verifyTypes(const [NumType.i32, NumType.f64], const [],
+        trace: ['f64.store', memory.index, offset, align]));
+    writeByte(0x39);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.store8` instruction.
+  void i32_store8(Memory memory, int offset, [int align = 0]) {
+    assert(align == 0);
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [],
+        trace: ['i32.store8', memory.index, offset, align]));
+    writeByte(0x3A);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i32.store16` instruction.
+  void i32_store16(Memory memory, int offset, [int align = 1]) {
+    assert(align >= 0 && align <= 1);
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [],
+        trace: ['i32.store16', memory.index, offset, align]));
+    writeByte(0x3B);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.store8` instruction.
+  void i64_store8(Memory memory, int offset, [int align = 0]) {
+    assert(align == 0);
+    assert(_verifyTypes(const [NumType.i32, NumType.i64], const [],
+        trace: ['i64.store8', memory.index, offset, align]));
+    writeByte(0x3C);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.store16` instruction.
+  void i64_store16(Memory memory, int offset, [int align = 1]) {
+    assert(align >= 0 && align <= 1);
+    assert(_verifyTypes(const [NumType.i32, NumType.i64], const [],
+        trace: ['i64.store16', memory.index, offset, align]));
+    writeByte(0x3D);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit an `i64.store32` instruction.
+  void i64_store32(Memory memory, int offset, [int align = 2]) {
+    assert(align >= 0 && align <= 2);
+    assert(_verifyTypes(const [NumType.i32, NumType.i64], const [],
+        trace: ['i64.store32', memory.index, offset, align]));
+    writeByte(0x3E);
+    _writeMemArg(memory, offset, align);
+  }
+
+  /// Emit a `memory.size` instruction.
+  void memory_size(Memory memory) {
+    assert(_verifyTypes(const [], const [NumType.i32]));
+    writeByte(0x3F);
+    writeUnsigned(memory.index);
+  }
+
+  /// Emit a `memory.grow` instruction.
+  void memory_grow(Memory memory) {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32]));
+    writeByte(0x40);
+    writeUnsigned(memory.index);
+  }
+
+  // Reference instructions
+
+  /// Emit a `ref.null` instruction.
+  void ref_null(HeapType heapType) {
+    assert(_verifyTypes(const [], [RefType(heapType, nullable: true)],
+        trace: ['ref.null', heapType]));
+    writeByte(0xD0);
+    write(heapType);
+  }
+
+  /// Emit a `ref.is_null` instruction.
+  void ref_is_null() {
+    assert(_verifyTypes(const [RefType.any()], const [NumType.i32],
+        trace: const ['ref.is_null']));
+    writeByte(0xD1);
+  }
+
+  /// Emit a `ref.func` instruction.
+  void ref_func(BaseFunction function) {
+    assert(_verifyTypes(const [], [RefType.def(function.type, nullable: false)],
+        trace: ['ref.func', function]));
+    writeByte(0xD2);
+    writeUnsigned(function.index);
+  }
+
+  /// Emit a `ref.as_non_null` instruction.
+  void ref_as_non_null() {
+    assert(_verifyTypes(
+        const [RefType.any()], [_topOfStack.withNullability(false)],
+        trace: const ['ref.as_non_null']));
+    writeByte(0xD3);
+  }
+
+  /// Emit a `br_on_null` instruction.
+  void br_on_null(Label label) {
+    assert(_verifyTypes(
+        const [RefType.any()], [_topOfStack.withNullability(false)],
+        trace: ['br_on_null', label]));
+    assert(_verifyBranchTypes(label, 1));
+    writeByte(0xD4);
+    _writeLabel(label);
+  }
+
+  /// Emit a `ref.eq` instruction.
+  void ref_eq() {
+    assert(_verifyTypes(const [RefType.eq(), RefType.eq()], const [NumType.i32],
+        trace: const ['ref.eq']));
+    writeByte(0xD5);
+  }
+
+  /// Emit a `br_on_non_null` instruction.
+  void br_on_non_null(Label label) {
+    assert(_verifyBranchTypes(label, 1, [_topOfStack.withNullability(false)]));
+    assert(_verifyTypes(const [RefType.any()], const [],
+        trace: ['br_on_non_null', label]));
+    writeByte(0xD6);
+    _writeLabel(label);
+  }
+
+  /// Emit a `struct.new_with_rtt` instruction.
+  void struct_new_with_rtt(StructType structType) {
+    assert(_verifyTypes(
+        [...structType.fields.map((f) => f.type.unpacked), Rtt(structType)],
+        [RefType.def(structType, nullable: false)],
+        trace: ['struct.new_with_rtt', structType]));
+    writeBytes(const [0xFB, 0x01]);
+    writeUnsigned(structType.index);
+  }
+
+  /// Emit a `struct.new_default_with_rtt` instruction.
+  void struct_new_default_with_rtt(StructType structType) {
+    assert(_verifyTypes(
+        [Rtt(structType)], [RefType.def(structType, nullable: false)],
+        trace: ['struct.new_default_with_rtt', structType]));
+    writeBytes(const [0xFB, 0x02]);
+    writeUnsigned(structType.index);
+  }
+
+  /// Emit a `struct.get` instruction.
+  void struct_get(StructType structType, int fieldIndex) {
+    assert(structType.fields[fieldIndex].type is ValueType);
+    assert(_verifyTypes([RefType.def(structType, nullable: true)],
+        [structType.fields[fieldIndex].type.unpacked],
+        trace: ['struct.get', structType, fieldIndex]));
+    writeBytes(const [0xFB, 0x03]);
+    writeUnsigned(structType.index);
+    writeUnsigned(fieldIndex);
+  }
+
+  /// Emit a `struct.get_s` instruction.
+  void struct_get_s(StructType structType, int fieldIndex) {
+    assert(structType.fields[fieldIndex].type is PackedType);
+    assert(_verifyTypes([RefType.def(structType, nullable: true)],
+        [structType.fields[fieldIndex].type.unpacked],
+        trace: ['struct.get_s', structType, fieldIndex]));
+    writeBytes(const [0xFB, 0x04]);
+    writeUnsigned(structType.index);
+    writeUnsigned(fieldIndex);
+  }
+
+  /// Emit a `struct.get_u` instruction.
+  void struct_get_u(StructType structType, int fieldIndex) {
+    assert(structType.fields[fieldIndex].type is PackedType);
+    assert(_verifyTypes([RefType.def(structType, nullable: true)],
+        [structType.fields[fieldIndex].type.unpacked],
+        trace: ['struct.get_u', structType, fieldIndex]));
+    writeBytes(const [0xFB, 0x05]);
+    writeUnsigned(structType.index);
+    writeUnsigned(fieldIndex);
+  }
+
+  /// Emit a `struct.set` instruction.
+  void struct_set(StructType structType, int fieldIndex) {
+    assert(_verifyTypes([
+      RefType.def(structType, nullable: true),
+      structType.fields[fieldIndex].type.unpacked
+    ], const [], trace: [
+      'struct.set',
+      structType,
+      fieldIndex
+    ]));
+    writeBytes(const [0xFB, 0x06]);
+    writeUnsigned(structType.index);
+    writeUnsigned(fieldIndex);
+  }
+
+  /// Emit a `struct.new` instruction.
+  void struct_new(StructType structType) {
+    assert(_verifyTypes([...structType.fields.map((f) => f.type.unpacked)],
+        [RefType.def(structType, nullable: false)],
+        trace: ['struct.new', structType]));
+    writeBytes(const [0xFB, 0x07]);
+    writeUnsigned(structType.index);
+  }
+
+  /// Emit a `struct.new_default` instruction.
+  void struct_new_default(StructType structType) {
+    assert(_verifyTypes(const [], [RefType.def(structType, nullable: false)],
+        trace: ['struct.new_default', structType]));
+    writeBytes(const [0xFB, 0x08]);
+    writeUnsigned(structType.index);
+  }
+
+  /// Emit an `array.new_with_rtt` instruction.
+  void array_new_with_rtt(ArrayType arrayType) {
+    assert(_verifyTypes(
+        [arrayType.elementType.type.unpacked, NumType.i32, Rtt(arrayType)],
+        [RefType.def(arrayType, nullable: false)],
+        trace: ['array.new_with_rtt', arrayType]));
+    writeBytes(const [0xFB, 0x11]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.new_default_with_rtt` instruction.
+  void array_new_default_with_rtt(ArrayType arrayType) {
+    assert(_verifyTypes([NumType.i32, Rtt(arrayType)],
+        [RefType.def(arrayType, nullable: false)],
+        trace: ['array.new_default_with_rtt', arrayType]));
+    writeBytes(const [0xFB, 0x12]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.get` instruction.
+  void array_get(ArrayType arrayType) {
+    assert(arrayType.elementType.type is ValueType);
+    assert(_verifyTypes([RefType.def(arrayType, nullable: true), NumType.i32],
+        [arrayType.elementType.type.unpacked],
+        trace: ['array.get', arrayType]));
+    writeBytes(const [0xFB, 0x13]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.get_s` instruction.
+  void array_get_s(ArrayType arrayType) {
+    assert(arrayType.elementType.type is PackedType);
+    assert(_verifyTypes([RefType.def(arrayType, nullable: true), NumType.i32],
+        [arrayType.elementType.type.unpacked],
+        trace: ['array.get_s', arrayType]));
+    writeBytes(const [0xFB, 0x14]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.get_u` instruction.
+  void array_get_u(ArrayType arrayType) {
+    assert(arrayType.elementType.type is PackedType);
+    assert(_verifyTypes([RefType.def(arrayType, nullable: true), NumType.i32],
+        [arrayType.elementType.type.unpacked],
+        trace: ['array.get_u', arrayType]));
+    writeBytes(const [0xFB, 0x15]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.set` instruction.
+  void array_set(ArrayType arrayType) {
+    assert(_verifyTypes([
+      RefType.def(arrayType, nullable: true),
+      NumType.i32,
+      arrayType.elementType.type.unpacked
+    ], const [], trace: [
+      'array.set',
+      arrayType
+    ]));
+    writeBytes(const [0xFB, 0x16]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.len` instruction.
+  void array_len(ArrayType arrayType) {
+    assert(_verifyTypes(
+        [RefType.def(arrayType, nullable: true)], const [NumType.i32],
+        trace: ['array.len', arrayType]));
+    writeBytes(const [0xFB, 0x17]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.init` instruction.
+  void array_init(ArrayType arrayType, int length) {
+    ValueType elementType = arrayType.elementType.type.unpacked;
+    assert(_verifyTypes([...List.filled(length, elementType), Rtt(arrayType)],
+        [RefType.def(arrayType, nullable: false)],
+        trace: ['array.init', arrayType, length]));
+    writeBytes(const [0xFB, 0x19]);
+    writeUnsigned(arrayType.index);
+    writeUnsigned(length);
+  }
+
+  /// Emit an `array.init_static` instruction.
+  void array_init_static(ArrayType arrayType, int length) {
+    ValueType elementType = arrayType.elementType.type.unpacked;
+    assert(_verifyTypes([...List.filled(length, elementType)],
+        [RefType.def(arrayType, nullable: false)],
+        trace: ['array.init_static', arrayType, length]));
+    writeBytes(const [0xFB, 0x1a]);
+    writeUnsigned(arrayType.index);
+    writeUnsigned(length);
+  }
+
+  /// Emit an `array.new` instruction.
+  void array_new(ArrayType arrayType) {
+    assert(_verifyTypes([arrayType.elementType.type.unpacked, NumType.i32],
+        [RefType.def(arrayType, nullable: false)],
+        trace: ['array.new', arrayType]));
+    writeBytes(const [0xFB, 0x1b]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.new_default` instruction.
+  void array_new_default(ArrayType arrayType) {
+    assert(_verifyTypes(
+        [NumType.i32], [RefType.def(arrayType, nullable: false)],
+        trace: ['array.new_default', arrayType]));
+    writeBytes(const [0xFB, 0x1c]);
+    writeUnsigned(arrayType.index);
+  }
+
+  /// Emit an `array.init_from_data_static` instruction.
+  void array_init_from_data_static(ArrayType arrayType, DataSegment data) {
+    assert(arrayType.elementType.type.isPrimitive);
+    assert(_verifyTypes(
+        [NumType.i32, NumType.i32], [RefType.def(arrayType, nullable: false)],
+        trace: ['array.init_from_data_static', arrayType, data.index]));
+    writeBytes(const [0xFB, 0x1d]);
+    writeUnsigned(arrayType.index);
+    writeUnsigned(data.index);
+    if (isGlobalInitializer) module.dataReferencedFromGlobalInitializer = true;
+  }
+
+  /// Emit an `array.init_from_data` instruction.
+  void array_init_from_data(ArrayType arrayType, DataSegment data) {
+    assert(arrayType.elementType.type.isPrimitive);
+    assert(_verifyTypes([NumType.i32, NumType.i32, Rtt(arrayType)],
+        [RefType.def(arrayType, nullable: false)],
+        trace: ['array.init_from_data', arrayType, data.index]));
+    writeBytes(const [0xFB, 0x1e]);
+    writeUnsigned(arrayType.index);
+    writeUnsigned(data.index);
+    if (isGlobalInitializer) module.dataReferencedFromGlobalInitializer = true;
+  }
+
+  /// Emit an `i31.new` instruction.
+  void i31_new() {
+    assert(_verifyTypes(const [NumType.i32], const [RefType.i31()],
+        trace: const ['i31.new']));
+    writeBytes(const [0xFB, 0x20]);
+  }
+
+  /// Emit an `i31.get_s` instruction.
+  void i31_get_s() {
+    assert(_verifyTypes(const [RefType.i31()], const [NumType.i32],
+        trace: const ['i31.get_s']));
+    writeBytes(const [0xFB, 0x21]);
+  }
+
+  /// Emit an `i31.get_u` instruction.
+  void i31_get_u() {
+    assert(_verifyTypes(const [RefType.i31()], const [NumType.i32],
+        trace: const ['i31.get_u']));
+    writeBytes(const [0xFB, 0x22]);
+  }
+
+  /// Emit an `rtt.canon` instruction.
+  void rtt_canon(DefType defType) {
+    assert(_verifyTypes(const [], [Rtt(defType, defType.depth)],
+        trace: ['rtt.canon', defType]));
+    writeBytes(const [0xFB, 0x30]);
+    writeSigned(defType.index);
+  }
+
+  bool _verifyRttSub(DefType subType) {
+    if (!reachable) {
+      return _debugTrace(['rtt.sub', subType], reachableAfter: false);
+    }
+    final ValueType input = _topOfStack;
+    if (input is! Rtt) _reportError("Expected rtt, but stack contained $input");
+    final int? depth = input.depth;
+    if (depth == null) _reportError("Expected rtt with known depth");
+    final DefType superType = input.defType;
+    if (!subType.isSubtypeOf(superType)) {
+      _reportError("Expected supertype of $subType, but got $superType");
+    }
+    return _verifyTypes([input], [Rtt(subType, depth + 1)],
+        trace: ['rtt.sub', subType]);
+  }
+
+  /// Emit an `rtt.sub` instruction.
+  void rtt_sub(DefType defType) {
+    assert(_verifyRttSub(defType));
+    writeBytes(const [0xFB, 0x31]);
+    writeSigned(defType.index);
+  }
+
+  bool _verifyCast(List<ValueType> Function(List<ValueType>) outputsFun,
+      {List<Object>? trace}) {
+    if (!reachable) {
+      return _debugTrace(trace, reachableAfter: false);
+    }
+    final stack = _stack(2);
+    final ValueType value = stack[0];
+    final ValueType rtt = stack[1];
+    if (rtt is! Rtt ||
+        !value.isSubtypeOf(const RefType.data(nullable: true)) &&
+            !value.isSubtypeOf(const RefType.func(nullable: true))) {
+      _reportError("Expected [data or func, rtt], but stack contained $stack");
+    }
+    return _verifyTypesFun(stack, outputsFun, trace: trace);
+  }
+
+  /// Emit a `ref.test` instruction.
+  void ref_test() {
+    assert(_verifyCast((_) => const [NumType.i32], trace: const ['ref.test']));
+    writeBytes(const [0xFB, 0x40]);
+  }
+
+  /// Emit a `ref.cast` instruction.
+  void ref_cast() {
+    assert(_verifyCast(
+        (inputs) => [
+              RefType.def((inputs[1] as Rtt).defType,
+                  nullable: inputs[0].nullable)
+            ],
+        trace: const ['ref.cast']));
+    writeBytes(const [0xFB, 0x41]);
+  }
+
+  /// Emit a `br_on_cast` instruction.
+  void br_on_cast(Label label) {
+    late final DefType targetType;
+    assert(_verifyCast((inputs) {
+      targetType = (inputs[1] as Rtt).defType;
+      return [inputs[0]];
+    }, trace: ['br_on_cast', label]));
+    assert(_verifyBranchTypes(
+        label, 1, [RefType.def(targetType, nullable: false)]));
+    writeBytes(const [0xFB, 0x42]);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_on_cast_fail` instruction.
+  void br_on_cast_fail(Label label) {
+    assert(_verifyBranchTypes(label, 1, [_topOfStack]));
+    assert(_verifyCast(
+        (inputs) => [RefType.def((inputs[1] as Rtt).defType, nullable: false)],
+        trace: ['br_on_cast_fail', label]));
+    writeBytes(const [0xFB, 0x43]);
+    _writeLabel(label);
+  }
+
+  bool _verifyCastStatic(List<ValueType> Function(List<ValueType>) outputsFun,
+      {List<Object>? trace}) {
+    if (!reachable) {
+      return _debugTrace(trace, reachableAfter: false);
+    }
+    final ValueType value = _topOfStack;
+    if (!value.isSubtypeOf(const RefType.data(nullable: true)) &&
+        !value.isSubtypeOf(const RefType.func(nullable: true))) {
+      _reportError("Expected [data or func], but stack contained [$value]");
+    }
+    return _verifyTypesFun([value], outputsFun, trace: trace);
+  }
+
+  /// Emit a `ref.test_static` instruction.
+  void ref_test_static(DefType targetType) {
+    assert(_verifyCastStatic((_) => const [NumType.i32],
+        trace: ['ref.test_static', targetType]));
+    writeBytes(const [0xFB, 0x44]);
+    writeSigned(targetType.index);
+  }
+
+  /// Emit a `ref.cast_static` instruction.
+  void ref_cast_static(DefType targetType) {
+    assert(_verifyCastStatic(
+        (inputs) => [RefType.def(targetType, nullable: inputs[0].nullable)],
+        trace: ['ref.cast_static', targetType]));
+    writeBytes(const [0xFB, 0x45]);
+    writeSigned(targetType.index);
+  }
+
+  /// Emit a `br_on_cast_static` instruction.
+  void br_on_cast_static(Label label, DefType targetType) {
+    assert(_verifyCastStatic((inputs) {
+      return [inputs[0]];
+    }, trace: ['br_on_cast_static', label, targetType]));
+    assert(_verifyBranchTypes(
+        label, 1, [RefType.def(targetType, nullable: false)]));
+    writeBytes(const [0xFB, 0x46]);
+    _writeLabel(label);
+    writeSigned(targetType.index);
+  }
+
+  /// Emit a `br_on_cast_static_fail` instruction.
+  void br_on_cast_static_fail(Label label, DefType targetType) {
+    assert(_verifyBranchTypes(label, 1, [_topOfStack]));
+    assert(_verifyCast((inputs) => [RefType.def(targetType, nullable: false)],
+        trace: ['br_on_cast_static_fail', label, targetType]));
+    writeBytes(const [0xFB, 0x47]);
+    _writeLabel(label);
+    writeSigned(targetType.index);
+  }
+
+  /// Emit a `ref.is_func` instruction.
+  void ref_is_func() {
+    assert(_verifyTypes(const [RefType.any()], const [NumType.i32],
+        trace: const ['ref.is_func']));
+    writeBytes(const [0xFB, 0x50]);
+  }
+
+  /// Emit a `ref.is_data` instruction.
+  void ref_is_data() {
+    assert(_verifyTypes(const [RefType.any()], const [NumType.i32],
+        trace: const ['ref.is_data']));
+    writeBytes(const [0xFB, 0x51]);
+  }
+
+  /// Emit a `ref.is_i31` instruction.
+  void ref_is_i31() {
+    assert(_verifyTypes(const [RefType.any()], const [NumType.i32],
+        trace: const ['ref.is_i31']));
+    writeBytes(const [0xFB, 0x52]);
+  }
+
+  /// Emit a `ref.as_func` instruction.
+  void ref_as_func() {
+    assert(_verifyTypes(
+        const [RefType.any()], const [RefType.func(nullable: false)],
+        trace: const ['ref.as_func']));
+    writeBytes(const [0xFB, 0x58]);
+  }
+
+  /// Emit a `ref.as_data` instruction.
+  void ref_as_data() {
+    assert(_verifyTypes(
+        const [RefType.any()], const [RefType.data(nullable: false)],
+        trace: const ['ref.as_data']));
+    writeBytes(const [0xFB, 0x59]);
+  }
+
+  /// Emit a `ref.as_i31` instruction.
+  void ref_as_i31() {
+    assert(_verifyTypes(
+        const [RefType.any()], const [RefType.i31(nullable: false)],
+        trace: const ['ref.as_i31']));
+    writeBytes(const [0xFB, 0x5A]);
+  }
+
+  /// Emit a `br_on_func` instruction.
+  void br_on_func(Label label) {
+    assert(_verifyTypes(const [RefType.any()], [_topOfStack],
+        trace: ['br_on_func', label]));
+    assert(_verifyBranchTypes(label, 1, const [RefType.func(nullable: false)]));
+    writeBytes(const [0xFB, 0x60]);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_on_data` instruction.
+  void br_on_data(Label label) {
+    assert(_verifyTypes(const [RefType.any()], [_topOfStack],
+        trace: ['br_on_data', label]));
+    assert(_verifyBranchTypes(label, 1, const [RefType.data(nullable: false)]));
+    writeBytes(const [0xFB, 0x61]);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_on_i31` instruction.
+  void br_on_i31(Label label) {
+    assert(_verifyTypes(const [RefType.any()], [_topOfStack],
+        trace: ['br_on_i31', label]));
+    assert(_verifyBranchTypes(label, 1, const [RefType.i31(nullable: false)]));
+    writeBytes(const [0xFB, 0x62]);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_on_non_func` instruction.
+  void br_on_non_func(Label label) {
+    assert(_verifyBranchTypes(label, 1, [_topOfStack]));
+    assert(_verifyTypes(
+        const [RefType.any()], const [RefType.func(nullable: false)],
+        trace: ['br_on_non_func', label]));
+    writeBytes(const [0xFB, 0x63]);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_on_non_data` instruction.
+  void br_on_non_data(Label label) {
+    assert(_verifyBranchTypes(label, 1, [_topOfStack]));
+    assert(_verifyTypes(
+        const [RefType.any()], const [RefType.data(nullable: false)],
+        trace: ['br_on_non_data', label]));
+    writeBytes(const [0xFB, 0x64]);
+    _writeLabel(label);
+  }
+
+  /// Emit a `br_on_non_i31` instruction.
+  void br_on_non_i31(Label label) {
+    assert(_verifyBranchTypes(label, 1, [_topOfStack]));
+    assert(_verifyTypes(
+        const [RefType.any()], const [RefType.i31(nullable: false)],
+        trace: ['br_on_non_i31', label]));
+    writeBytes(const [0xFB, 0x65]);
+    _writeLabel(label);
+  }
+
+  // Numeric instructions
+
+  /// Emit an `i32.const` instruction.
+  void i32_const(int value) {
+    assert(_verifyTypes(const [], const [NumType.i32],
+        trace: ['i32.const', value]));
+    assert(-1 << 31 <= value && value < 1 << 31);
+    writeByte(0x41);
+    writeSigned(value);
+  }
+
+  /// Emit an `i64.const` instruction.
+  void i64_const(int value) {
+    assert(_verifyTypes(const [], const [NumType.i64],
+        trace: ['i64.const', value]));
+    writeByte(0x42);
+    writeSigned(value);
+  }
+
+  /// Emit an `f32.const` instruction.
+  void f32_const(double value) {
+    assert(_verifyTypes(const [], const [NumType.f32],
+        trace: ['f32.const', value]));
+    writeByte(0x43);
+    writeF32(value);
+  }
+
+  /// Emit an `f64.const` instruction.
+  void f64_const(double value) {
+    assert(_verifyTypes(const [], const [NumType.f64],
+        trace: ['f64.const', value]));
+    writeByte(0x44);
+    writeF64(value);
+  }
+
+  /// Emit an `i32.eqz` instruction.
+  void i32_eqz() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: const ['i32.eqz']));
+    writeByte(0x45);
+  }
+
+  /// Emit an `i32.eq` instruction.
+  void i32_eq() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.eq']));
+    writeByte(0x46);
+  }
+
+  /// Emit an `i32.ne` instruction.
+  void i32_ne() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.ne']));
+    writeByte(0x47);
+  }
+
+  /// Emit an `i32.lt_s` instruction.
+  void i32_lt_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.lt_s']));
+    writeByte(0x48);
+  }
+
+  /// Emit an `i32.lt_u` instruction.
+  void i32_lt_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.lt_u']));
+    writeByte(0x49);
+  }
+
+  /// Emit an `i32.gt_s` instruction.
+  void i32_gt_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.gt_s']));
+    writeByte(0x4A);
+  }
+
+  /// Emit an `i32.gt_u` instruction.
+  void i32_gt_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.gt_u']));
+    writeByte(0x4B);
+  }
+
+  /// Emit an `i32.le_s` instruction.
+  void i32_le_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.le_s']));
+    writeByte(0x4C);
+  }
+
+  /// Emit an `i32.le_u` instruction.
+  void i32_le_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.le_u']));
+    writeByte(0x4D);
+  }
+
+  /// Emit an `i32.ge_s` instruction.
+  void i32_ge_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.ge_s']));
+    writeByte(0x4E);
+  }
+
+  /// Emit an `i32.ge_u` instruction.
+  void i32_ge_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.ge_u']));
+    writeByte(0x4F);
+  }
+
+  /// Emit an `i64.eqz` instruction.
+  void i64_eqz() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i32],
+        trace: const ['i64.eqz']));
+    writeByte(0x50);
+  }
+
+  /// Emit an `i64.eq` instruction.
+  void i64_eq() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.eq']));
+    writeByte(0x51);
+  }
+
+  /// Emit an `i64.ne` instruction.
+  void i64_ne() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.ne']));
+    writeByte(0x52);
+  }
+
+  /// Emit an `i64.lt_s` instruction.
+  void i64_lt_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.lt_s']));
+    writeByte(0x53);
+  }
+
+  /// Emit an `i64.lt_u` instruction.
+  void i64_lt_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.lt_u']));
+    writeByte(0x54);
+  }
+
+  /// Emit an `i64.gt_s` instruction.
+  void i64_gt_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.gt_s']));
+    writeByte(0x55);
+  }
+
+  /// Emit an `i64.gt_u` instruction.
+  void i64_gt_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.gt_u']));
+    writeByte(0x56);
+  }
+
+  /// Emit an `i64.le_s` instruction.
+  void i64_le_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.le_s']));
+    writeByte(0x57);
+  }
+
+  /// Emit an `i64.le_u` instruction.
+  void i64_le_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.le_u']));
+    writeByte(0x58);
+  }
+
+  /// Emit an `i64.ge_s` instruction.
+  void i64_ge_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.ge_s']));
+    writeByte(0x59);
+  }
+
+  /// Emit an `i64.ge_u` instruction.
+  void i64_ge_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i32],
+        trace: const ['i64.ge_u']));
+    writeByte(0x5A);
+  }
+
+  /// Emit an `f32.eq` instruction.
+  void f32_eq() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.i32],
+        trace: const ['f32.eq']));
+    writeByte(0x5B);
+  }
+
+  /// Emit an `f32.ne` instruction.
+  void f32_ne() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.i32],
+        trace: const ['f32.ne']));
+    writeByte(0x5C);
+  }
+
+  /// Emit an `f32.lt` instruction.
+  void f32_lt() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.i32],
+        trace: const ['f32.lt']));
+    writeByte(0x5D);
+  }
+
+  /// Emit an `f32.gt` instruction.
+  void f32_gt() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.i32],
+        trace: const ['f32.gt']));
+    writeByte(0x5E);
+  }
+
+  /// Emit an `f32.le` instruction.
+  void f32_le() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.i32],
+        trace: const ['f32.le']));
+    writeByte(0x5F);
+  }
+
+  /// Emit an `f32.ge` instruction.
+  void f32_ge() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.i32],
+        trace: const ['f32.ge']));
+    writeByte(0x60);
+  }
+
+  /// Emit an `f64.eq` instruction.
+  void f64_eq() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.i32],
+        trace: const ['f64.eq']));
+    writeByte(0x61);
+  }
+
+  /// Emit an `f64.ne` instruction.
+  void f64_ne() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.i32],
+        trace: const ['f64.ne']));
+    writeByte(0x62);
+  }
+
+  /// Emit an `f64.lt` instruction.
+  void f64_lt() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.i32],
+        trace: const ['f64.lt']));
+    writeByte(0x63);
+  }
+
+  /// Emit an `f64.gt` instruction.
+  void f64_gt() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.i32],
+        trace: const ['f64.gt']));
+    writeByte(0x64);
+  }
+
+  /// Emit an `f64.le` instruction.
+  void f64_le() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.i32],
+        trace: const ['f64.le']));
+    writeByte(0x65);
+  }
+
+  /// Emit an `f64.ge` instruction.
+  void f64_ge() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.i32],
+        trace: const ['f64.ge']));
+    writeByte(0x66);
+  }
+
+  /// Emit an `i32.clz` instruction.
+  void i32_clz() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: const ['i32.clz']));
+    writeByte(0x67);
+  }
+
+  /// Emit an `i32.ctz` instruction.
+  void i32_ctz() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: const ['i32.ctz']));
+    writeByte(0x68);
+  }
+
+  /// Emit an `i32.popcnt` instruction.
+  void i32_popcnt() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: const ['i32.popcnt']));
+    writeByte(0x69);
+  }
+
+  /// Emit an `i32.add` instruction.
+  void i32_add() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.add']));
+    writeByte(0x6A);
+  }
+
+  /// Emit an `i32.sub` instruction.
+  void i32_sub() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.sub']));
+    writeByte(0x6B);
+  }
+
+  /// Emit an `i32.mul` instruction.
+  void i32_mul() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.mul']));
+    writeByte(0x6C);
+  }
+
+  /// Emit an `i32.div_s` instruction.
+  void i32_div_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.div_s']));
+    writeByte(0x6D);
+  }
+
+  /// Emit an `i32.div_u` instruction.
+  void i32_div_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.div_u']));
+    writeByte(0x6E);
+  }
+
+  /// Emit an `i32.rem_s` instruction.
+  void i32_rem_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.rem_s']));
+    writeByte(0x6F);
+  }
+
+  /// Emit an `i32.rem_u` instruction.
+  void i32_rem_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.rem_u']));
+    writeByte(0x70);
+  }
+
+  /// Emit an `i32.and` instruction.
+  void i32_and() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.and']));
+    writeByte(0x71);
+  }
+
+  /// Emit an `i32.or` instruction.
+  void i32_or() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.or']));
+    writeByte(0x72);
+  }
+
+  /// Emit an `i32.xor` instruction.
+  void i32_xor() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.xor']));
+    writeByte(0x73);
+  }
+
+  /// Emit an `i32.shl` instruction.
+  void i32_shl() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.shl']));
+    writeByte(0x74);
+  }
+
+  /// Emit an `i32.shr_s` instruction.
+  void i32_shr_s() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.shr_s']));
+    writeByte(0x75);
+  }
+
+  /// Emit an `i32.shr_u` instruction.
+  void i32_shr_u() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.shr_u']));
+    writeByte(0x76);
+  }
+
+  /// Emit an `i32.rotl` instruction.
+  void i32_rotl() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.rotl']));
+    writeByte(0x77);
+  }
+
+  /// Emit an `i32.rotr` instruction.
+  void i32_rotr() {
+    assert(_verifyTypes(const [NumType.i32, NumType.i32], const [NumType.i32],
+        trace: const ['i32.rotr']));
+    writeByte(0x78);
+  }
+
+  /// Emit an `i64.clz` instruction.
+  void i64_clz() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i64],
+        trace: const ['i64.clz']));
+    writeByte(0x79);
+  }
+
+  /// Emit an `i64.ctz` instruction.
+  void i64_ctz() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i64],
+        trace: const ['i64.ctz']));
+    writeByte(0x7A);
+  }
+
+  /// Emit an `i64.popcnt` instruction.
+  void i64_popcnt() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i64],
+        trace: const ['i64.popcnt']));
+    writeByte(0x7B);
+  }
+
+  /// Emit an `i64.add` instruction.
+  void i64_add() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.add']));
+    writeByte(0x7C);
+  }
+
+  /// Emit an `i64.sub` instruction.
+  void i64_sub() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.sub']));
+    writeByte(0x7D);
+  }
+
+  /// Emit an `i64.mul` instruction.
+  void i64_mul() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.mul']));
+    writeByte(0x7E);
+  }
+
+  /// Emit an `i64.div_s` instruction.
+  void i64_div_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.div_s']));
+    writeByte(0x7F);
+  }
+
+  /// Emit an `i64.div_u` instruction.
+  void i64_div_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.div_u']));
+    writeByte(0x80);
+  }
+
+  /// Emit an `i64.rem_s` instruction.
+  void i64_rem_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.rem_s']));
+    writeByte(0x81);
+  }
+
+  /// Emit an `i64.rem_u` instruction.
+  void i64_rem_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.rem_u']));
+    writeByte(0x82);
+  }
+
+  /// Emit an `i64.and` instruction.
+  void i64_and() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.and']));
+    writeByte(0x83);
+  }
+
+  /// Emit an `i64.or` instruction.
+  void i64_or() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.or']));
+    writeByte(0x84);
+  }
+
+  /// Emit an `i64.xor` instruction.
+  void i64_xor() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.xor']));
+    writeByte(0x85);
+  }
+
+  /// Emit an `i64.shl` instruction.
+  void i64_shl() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.shl']));
+    writeByte(0x86);
+  }
+
+  /// Emit an `i64.shr_s` instruction.
+  void i64_shr_s() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.shr_s']));
+    writeByte(0x87);
+  }
+
+  /// Emit an `i64.shr_u` instruction.
+  void i64_shr_u() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.shr_u']));
+    writeByte(0x88);
+  }
+
+  /// Emit an `i64.rotl` instruction.
+  void i64_rotl() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.rotl']));
+    writeByte(0x89);
+  }
+
+  /// Emit an `i64.rotr` instruction.
+  void i64_rotr() {
+    assert(_verifyTypes(const [NumType.i64, NumType.i64], const [NumType.i64],
+        trace: const ['i64.rotr']));
+    writeByte(0x8A);
+  }
+
+  /// Emit an `f32.abs` instruction.
+  void f32_abs() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.abs']));
+    writeByte(0x8B);
+  }
+
+  /// Emit an `f32.neg` instruction.
+  void f32_neg() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.neg']));
+    writeByte(0x8C);
+  }
+
+  /// Emit an `f32.ceil` instruction.
+  void f32_ceil() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.ceil']));
+    writeByte(0x8D);
+  }
+
+  /// Emit an `f32.floor` instruction.
+  void f32_floor() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.floor']));
+    writeByte(0x8E);
+  }
+
+  /// Emit an `f32.trunc` instruction.
+  void f32_trunc() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.trunc']));
+    writeByte(0x8F);
+  }
+
+  /// Emit an `f32.nearest` instruction.
+  void f32_nearest() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.nearest']));
+    writeByte(0x90);
+  }
+
+  /// Emit an `f32.sqrt` instruction.
+  void f32_sqrt() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f32],
+        trace: const ['f32.sqrt']));
+    writeByte(0x91);
+  }
+
+  /// Emit an `f32.add` instruction.
+  void f32_add() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.add']));
+    writeByte(0x92);
+  }
+
+  /// Emit an `f32.sub` instruction.
+  void f32_sub() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.sub']));
+    writeByte(0x93);
+  }
+
+  /// Emit an `f32.mul` instruction.
+  void f32_mul() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.mul']));
+    writeByte(0x94);
+  }
+
+  /// Emit an `f32.div` instruction.
+  void f32_div() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.div']));
+    writeByte(0x95);
+  }
+
+  /// Emit an `f32.min` instruction.
+  void f32_min() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.min']));
+    writeByte(0x96);
+  }
+
+  /// Emit an `f32.max` instruction.
+  void f32_max() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.max']));
+    writeByte(0x97);
+  }
+
+  /// Emit an `f32.copysign` instruction.
+  void f32_copysign() {
+    assert(_verifyTypes(const [NumType.f32, NumType.f32], const [NumType.f32],
+        trace: const ['f32.copysign']));
+    writeByte(0x98);
+  }
+
+  /// Emit an `f64.abs` instruction.
+  void f64_abs() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.abs']));
+    writeByte(0x99);
+  }
+
+  /// Emit an `f64.neg` instruction.
+  void f64_neg() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.neg']));
+    writeByte(0x9A);
+  }
+
+  /// Emit an `f64.ceil` instruction.
+  void f64_ceil() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.ceil']));
+    writeByte(0x9B);
+  }
+
+  /// Emit an `f64.floor` instruction.
+  void f64_floor() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.floor']));
+    writeByte(0x9C);
+  }
+
+  /// Emit an `f64.trunc` instruction.
+  void f64_trunc() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.trunc']));
+    writeByte(0x9D);
+  }
+
+  /// Emit an `f64.nearest` instruction.
+  void f64_nearest() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.nearest']));
+    writeByte(0x9E);
+  }
+
+  /// Emit an `f64.sqrt` instruction.
+  void f64_sqrt() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f64],
+        trace: const ['f64.sqrt']));
+    writeByte(0x9F);
+  }
+
+  /// Emit an `f64.add` instruction.
+  void f64_add() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.add']));
+    writeByte(0xA0);
+  }
+
+  /// Emit an `f64.sub` instruction.
+  void f64_sub() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.sub']));
+    writeByte(0xA1);
+  }
+
+  /// Emit an `f64.mul` instruction.
+  void f64_mul() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.mul']));
+    writeByte(0xA2);
+  }
+
+  /// Emit an `f64.div` instruction.
+  void f64_div() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.div']));
+    writeByte(0xA3);
+  }
+
+  /// Emit an `f64.min` instruction.
+  void f64_min() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.min']));
+    writeByte(0xA4);
+  }
+
+  /// Emit an `f64.max` instruction.
+  void f64_max() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.max']));
+    writeByte(0xA5);
+  }
+
+  /// Emit an `f64.copysign` instruction.
+  void f64_copysign() {
+    assert(_verifyTypes(const [NumType.f64, NumType.f64], const [NumType.f64],
+        trace: const ['f64.copysign']));
+    writeByte(0xA6);
+  }
+
+  /// Emit an `i32.wrap_i64` instruction.
+  void i32_wrap_i64() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i32],
+        trace: const ['i32.wrap_i64']));
+    writeByte(0xA7);
+  }
+
+  /// Emit an `i32.trunc_f32_s` instruction.
+  void i32_trunc_f32_s() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i32],
+        trace: const ['i32.trunc_f32_s']));
+    writeByte(0xA8);
+  }
+
+  /// Emit an `i32.trunc_f32_u` instruction.
+  void i32_trunc_f32_u() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i32],
+        trace: const ['i32.trunc_f32_u']));
+    writeByte(0xA9);
+  }
+
+  /// Emit an `i32.trunc_f64_s` instruction.
+  void i32_trunc_f64_s() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i32],
+        trace: const ['i32.trunc_f64_s']));
+    writeByte(0xAA);
+  }
+
+  /// Emit an `i32.trunc_f64_u` instruction.
+  void i32_trunc_f64_u() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i32],
+        trace: const ['i32.trunc_f64_u']));
+    writeByte(0xAB);
+  }
+
+  /// Emit an `i64.extend_i32_s` instruction.
+  void i64_extend_i32_s() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: const ['i64.extend_i32_s']));
+    writeByte(0xAC);
+  }
+
+  /// Emit an `i64.extend_i32_u` instruction.
+  void i64_extend_i32_u() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i64],
+        trace: const ['i64.extend_i32_u']));
+    writeByte(0xAD);
+  }
+
+  /// Emit an `i64.trunc_f32_s` instruction.
+  void i64_trunc_f32_s() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i64],
+        trace: const ['i64.trunc_f32_s']));
+    writeByte(0xAE);
+  }
+
+  /// Emit an `i64.trunc_f32_u` instruction.
+  void i64_trunc_f32_u() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i64],
+        trace: const ['i64.trunc_f32_u']));
+    writeByte(0xAF);
+  }
+
+  /// Emit an `i64.trunc_f64_s` instruction.
+  void i64_trunc_f64_s() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i64],
+        trace: const ['i64.trunc_f64_s']));
+    writeByte(0xB0);
+  }
+
+  /// Emit an `i64.trunc_f64_u` instruction.
+  void i64_trunc_f64_u() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i64],
+        trace: const ['i64.trunc_f64_u']));
+    writeByte(0xB1);
+  }
+
+  /// Emit an `f32.convert_i32_s` instruction.
+  void f32_convert_i32_s() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f32],
+        trace: const ['f32.convert_i32_s']));
+    writeByte(0xB2);
+  }
+
+  /// Emit an `f32.convert_i32_u` instruction.
+  void f32_convert_i32_u() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f32],
+        trace: const ['f32.convert_i32_u']));
+    writeByte(0xB3);
+  }
+
+  /// Emit an `f32.convert_i64_s` instruction.
+  void f32_convert_i64_s() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.f32],
+        trace: const ['f32.convert_i64_s']));
+    writeByte(0xB4);
+  }
+
+  /// Emit an `f32.convert_i64_u` instruction.
+  void f32_convert_i64_u() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.f32],
+        trace: const ['f32.convert_i64_u']));
+    writeByte(0xB5);
+  }
+
+  /// Emit an `f32.demote_f64` instruction.
+  void f32_demote_f64() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.f32],
+        trace: const ['f32.demote_f64']));
+    writeByte(0xB6);
+  }
+
+  /// Emit an `f64.convert_i32_s` instruction.
+  void f64_convert_i32_s() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f64],
+        trace: const ['f64.convert_i32_s']));
+    writeByte(0xB7);
+  }
+
+  /// Emit an `f64.convert_i32_u` instruction.
+  void f64_convert_i32_u() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f64],
+        trace: const ['f64.convert_i32_u']));
+    writeByte(0xB8);
+  }
+
+  /// Emit an `f64.convert_i64_s` instruction.
+  void f64_convert_i64_s() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.f64],
+        trace: const ['f64.convert_i64_s']));
+    writeByte(0xB9);
+  }
+
+  /// Emit an `f64.convert_i64_u` instruction.
+  void f64_convert_i64_u() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.f64],
+        trace: const ['f64.convert_i64_u']));
+    writeByte(0xBA);
+  }
+
+  /// Emit an `f64.promote_f32` instruction.
+  void f64_promote_f32() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.f64],
+        trace: const ['f64.promote_f32']));
+    writeByte(0xBB);
+  }
+
+  /// Emit an `i32.reinterpret_f32` instruction.
+  void i32_reinterpret_f32() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i32],
+        trace: const ['i32.reinterpret_f32']));
+    writeByte(0xBC);
+  }
+
+  /// Emit an `i64.reinterpret_f64` instruction.
+  void i64_reinterpret_f64() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i64],
+        trace: const ['i64.reinterpret_f64']));
+    writeByte(0xBD);
+  }
+
+  /// Emit an `f32.reinterpret_i32` instruction.
+  void f32_reinterpret_i32() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.f32],
+        trace: const ['f32.reinterpret_i32']));
+    writeByte(0xBE);
+  }
+
+  /// Emit an `f64.reinterpret_i64` instruction.
+  void f64_reinterpret_i64() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.f64],
+        trace: const ['f64.reinterpret_i64']));
+    writeByte(0xBF);
+  }
+
+  /// Emit an `i32.extend8_s` instruction.
+  void i32_extend8_s() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: const ['i32.extend8_s']));
+    writeByte(0xC0);
+  }
+
+  /// Emit an `i32.extend16_s` instruction.
+  void i32_extend16_s() {
+    assert(_verifyTypes(const [NumType.i32], const [NumType.i32],
+        trace: const ['i32.extend16_s']));
+    writeByte(0xC1);
+  }
+
+  /// Emit an `i64.extend8_s` instruction.
+  void i64_extend8_s() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i64],
+        trace: const ['i64.extend8_s']));
+    writeByte(0xC2);
+  }
+
+  /// Emit an `i64.extend16_s` instruction.
+  void i64_extend16_s() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i64],
+        trace: const ['i64.extend16_s']));
+    writeByte(0xC3);
+  }
+
+  /// Emit an `i64.extend32_s` instruction.
+  void i64_extend32_s() {
+    assert(_verifyTypes(const [NumType.i64], const [NumType.i64],
+        trace: const ['i64.extend32_s']));
+    writeByte(0xC4);
+  }
+
+  /// Emit an `i32.trunc_sat_f32_s` instruction.
+  void i32_trunc_sat_f32_s() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i32],
+        trace: const ['i32.trunc_sat_f32_s']));
+    writeBytes(const [0xFC, 0x00]);
+  }
+
+  /// Emit an `i32.trunc_sat_f32_u` instruction.
+  void i32_trunc_sat_f32_u() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i32],
+        trace: const ['i32.trunc_sat_f32_u']));
+    writeBytes(const [0xFC, 0x01]);
+  }
+
+  /// Emit an `i32.trunc_sat_f64_s` instruction.
+  void i32_trunc_sat_f64_s() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i32],
+        trace: const ['i32.trunc_sat_f64_s']));
+    writeBytes(const [0xFC, 0x02]);
+  }
+
+  /// Emit an `i32.trunc_sat_f64_u` instruction.
+  void i32_trunc_sat_f64_u() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i32],
+        trace: const ['i32.trunc_sat_f64_u']));
+    writeBytes(const [0xFC, 0x03]);
+  }
+
+  /// Emit an `i64.trunc_sat_f32_s` instruction.
+  void i64_trunc_sat_f32_s() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i64],
+        trace: const ['i64.trunc_sat_f32_s']));
+    writeBytes(const [0xFC, 0x04]);
+  }
+
+  /// Emit an `i64.trunc_sat_f32_u` instruction.
+  void i64_trunc_sat_f32_u() {
+    assert(_verifyTypes(const [NumType.f32], const [NumType.i64],
+        trace: const ['i64.trunc_sat_f32_u']));
+    writeBytes(const [0xFC, 0x05]);
+  }
+
+  /// Emit an `i64.trunc_sat_f64_s` instruction.
+  void i64_trunc_sat_f64_s() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i64],
+        trace: const ['i64.trunc_sat_f64_s']));
+    writeBytes(const [0xFC, 0x06]);
+  }
+
+  /// Emit an `i64.trunc_sat_f64_u` instruction.
+  void i64_trunc_sat_f64_u() {
+    assert(_verifyTypes(const [NumType.f64], const [NumType.i64],
+        trace: const ['i64.trunc_sat_f64_u']));
+    writeBytes(const [0xFC, 0x07]);
+  }
+}
diff --git a/pkg/wasm_builder/lib/src/module.dart b/pkg/wasm_builder/lib/src/module.dart
new file mode 100644
index 0000000..95ad8df
--- /dev/null
+++ b/pkg/wasm_builder/lib/src/module.dart
@@ -0,0 +1,820 @@
+// Copyright (c) 2022, 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 'dart:typed_data';
+
+import 'instructions.dart';
+import 'serialize.dart';
+import 'types.dart';
+
+/// A Wasm module.
+///
+/// Serves as a builder for building new modules.
+class Module with SerializerMixin {
+  final List<int>? watchPoints;
+
+  final Map<_FunctionTypeKey, FunctionType> functionTypeMap = {};
+
+  final List<DefType> defTypes = [];
+  final List<BaseFunction> functions = [];
+  final List<Table> tables = [];
+  final List<Memory> memories = [];
+  final List<DataSegment> dataSegments = [];
+  final List<Global> globals = [];
+  final List<Export> exports = [];
+  BaseFunction? startFunction = null;
+
+  bool anyFunctionsDefined = false;
+  bool anyGlobalsDefined = false;
+  bool dataReferencedFromGlobalInitializer = false;
+
+  int functionNameCount = 0;
+
+  /// Create a new, initially empty, module.
+  ///
+  /// The [watchPoints] is a list of byte offsets within the final module of
+  /// bytes to watch. When the module is serialized, the stack traces leading to
+  /// the production of all watched bytes are printed. This can be used to debug
+  /// runtime errors happening at specific offsets within the module.
+  Module({this.watchPoints}) {
+    if (watchPoints != null) {
+      SerializerMixin.traceEnabled = true;
+    }
+  }
+
+  /// All module imports (functions and globals).
+  Iterable<Import> get imports =>
+      functions.whereType<Import>().followedBy(globals.whereType<Import>());
+
+  /// All functions defined in the module.
+  Iterable<DefinedFunction> get definedFunctions =>
+      functions.whereType<DefinedFunction>();
+
+  /// Add a new function type to the module.
+  ///
+  /// All function types are canonicalized, such that identical types become
+  /// the same type definition in the module, assuming nominal type identity
+  /// of all inputs and outputs.
+  ///
+  /// Inputs and outputs can't be changed after the function type is created.
+  /// This means that recursive function types (without any non-function types
+  /// on the recursion path) are not supported.
+  FunctionType addFunctionType(
+      Iterable<ValueType> inputs, Iterable<ValueType> outputs,
+      {HeapType? superType}) {
+    final List<ValueType> inputList = List.unmodifiable(inputs);
+    final List<ValueType> outputList = List.unmodifiable(outputs);
+    final _FunctionTypeKey key = _FunctionTypeKey(inputList, outputList);
+    return functionTypeMap.putIfAbsent(key, () {
+      final type = FunctionType(inputList, outputList, superType: superType)
+        ..index = defTypes.length;
+      defTypes.add(type);
+      return type;
+    });
+  }
+
+  /// Add a new struct type to the module.
+  ///
+  /// Fields can be added later, by adding to the [fields] list. This enables
+  /// struct types to be recursive.
+  StructType addStructType(String name,
+      {Iterable<FieldType>? fields, HeapType? superType}) {
+    final type = StructType(name, fields: fields, superType: superType)
+      ..index = defTypes.length;
+    defTypes.add(type);
+    return type;
+  }
+
+  /// Add a new array type to the module.
+  ///
+  /// The element type can be specified later. This enables array types to be
+  /// recursive.
+  ArrayType addArrayType(String name,
+      {FieldType? elementType, HeapType? superType}) {
+    final type = ArrayType(name, elementType: elementType, superType: superType)
+      ..index = defTypes.length;
+    defTypes.add(type);
+    return type;
+  }
+
+  /// Add a new function to the module with the given function type.
+  ///
+  /// The [DefinedFunction.body] must be completed (including the terminating
+  /// `end`) before the module can be serialized.
+  DefinedFunction addFunction(FunctionType type, [String? name]) {
+    anyFunctionsDefined = true;
+    if (name != null) functionNameCount++;
+    final function = DefinedFunction(this, functions.length, type, name);
+    functions.add(function);
+    return function;
+  }
+
+  /// Add a new table to the module.
+  Table addTable(int minSize, [int? maxSize]) {
+    final table = Table(tables.length, minSize, maxSize);
+    tables.add(table);
+    return table;
+  }
+
+  /// Add a new memory to the module.
+  Memory addMemory(int minSize, [int? maxSize]) {
+    final memory = Memory(memories.length, minSize, maxSize);
+    memories.add(memory);
+    return memory;
+  }
+
+  /// Add a new data segment to the module.
+  ///
+  /// Either [memory] and [offset] must be both specified or both omitted. If
+  /// they are specified, the segment becomes an *active* segment, otherwise it
+  /// becomes a *passive* segment.
+  ///
+  /// If [initialContent] is specified, it defines the initial content of the
+  /// segment. The content can be extended later.
+  DataSegment addDataSegment(
+      [Uint8List? initialContent, Memory? memory, int? offset]) {
+    initialContent ??= Uint8List(0);
+    assert((memory != null) == (offset != null));
+    assert(memory == null ||
+        offset! >= 0 && offset + initialContent.length <= memory.minSize);
+    final DataSegment data =
+        DataSegment(dataSegments.length, initialContent, memory, offset);
+    dataSegments.add(data);
+    return data;
+  }
+
+  /// Add a global variable to the module.
+  ///
+  /// The [DefinedGlobal.initializer] must be completed (including the
+  /// terminating `end`) before the module can be serialized.
+  DefinedGlobal addGlobal(GlobalType type) {
+    anyGlobalsDefined = true;
+    final global = DefinedGlobal(this, globals.length, type);
+    globals.add(global);
+    return global;
+  }
+
+  /// Import a function into the module.
+  ///
+  /// All imported functions must be specified before any functions are declared
+  /// using [Module.addFunction].
+  ImportedFunction importFunction(String module, String name, FunctionType type,
+      [String? functionName]) {
+    if (anyFunctionsDefined) {
+      throw "All function imports must be specified before any definitions.";
+    }
+    if (functionName != null) functionNameCount++;
+    final function =
+        ImportedFunction(module, name, functions.length, type, functionName);
+    functions.add(function);
+    return function;
+  }
+
+  /// Import a global variable into the module.
+  ///
+  /// All imported globals must be specified before any globals are declared
+  /// using [Module.addGlobal].
+  ImportedGlobal importGlobal(String module, String name, GlobalType type) {
+    if (anyGlobalsDefined) {
+      throw "All global imports must be specified before any definitions.";
+    }
+    final global = ImportedGlobal(module, name, functions.length, type);
+    globals.add(global);
+    return global;
+  }
+
+  void _addExport(Export export) {
+    assert(!exports.any((e) => e.name == export.name), export.name);
+    exports.add(export);
+  }
+
+  /// Export a function from the module.
+  ///
+  /// All exports must have unique names.
+  void exportFunction(String name, BaseFunction function) {
+    function.exportedName = name;
+    _addExport(FunctionExport(name, function));
+  }
+
+  /// Export a global variable from the module.
+  ///
+  /// All exports must have unique names.
+  void exportGlobal(String name, Global global) {
+    exports.add(GlobalExport(name, global));
+  }
+
+  /// Serialize the module to its binary representation.
+  Uint8List encode({bool emitNameSection: true}) {
+    // Wasm module preamble: magic number, version 1.
+    writeBytes(const [0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00]);
+    TypeSection(this).serialize(this);
+    ImportSection(this).serialize(this);
+    FunctionSection(this).serialize(this);
+    TableSection(this).serialize(this);
+    MemorySection(this).serialize(this);
+    if (dataReferencedFromGlobalInitializer) {
+      DataCountSection(this).serialize(this);
+    }
+    GlobalSection(this).serialize(this);
+    ExportSection(this).serialize(this);
+    StartSection(this).serialize(this);
+    ElementSection(this).serialize(this);
+    if (!dataReferencedFromGlobalInitializer) {
+      DataCountSection(this).serialize(this);
+    }
+    CodeSection(this).serialize(this);
+    DataSection(this).serialize(this);
+    if (emitNameSection) {
+      NameSection(this).serialize(this);
+    }
+    return data;
+  }
+}
+
+class _FunctionTypeKey {
+  final List<ValueType> inputs;
+  final List<ValueType> outputs;
+
+  _FunctionTypeKey(this.inputs, this.outputs);
+
+  @override
+  bool operator ==(Object other) {
+    if (other is! _FunctionTypeKey) return false;
+    if (inputs.length != other.inputs.length) return false;
+    if (outputs.length != other.outputs.length) return false;
+    for (int i = 0; i < inputs.length; i++) {
+      if (inputs[i] != other.inputs[i]) return false;
+    }
+    for (int i = 0; i < outputs.length; i++) {
+      if (outputs[i] != other.outputs[i]) return false;
+    }
+    return true;
+  }
+
+  @override
+  int get hashCode {
+    int inputHash = 13;
+    for (var input in inputs) {
+      inputHash = inputHash * 17 + input.hashCode;
+    }
+    int outputHash = 23;
+    for (var output in outputs) {
+      outputHash = outputHash * 29 + output.hashCode;
+    }
+    return (inputHash * 2 + 1) * (outputHash * 2 + 1);
+  }
+}
+
+/// An (imported or defined) Wasm function.
+abstract class BaseFunction {
+  final int index;
+  final FunctionType type;
+  final String? functionName;
+  String? exportedName;
+
+  BaseFunction(this.index, this.type, this.functionName);
+}
+
+/// A function defined in the module.
+class DefinedFunction extends BaseFunction
+    with SerializerMixin
+    implements Serializable {
+  /// All local variables defined in the function, including its inputs.
+  final List<Local> locals = [];
+
+  /// The body of the function.
+  late final Instructions body;
+
+  DefinedFunction(Module module, int index, FunctionType type,
+      [String? functionName])
+      : super(index, type, functionName) {
+    for (ValueType paramType in type.inputs) {
+      addLocal(paramType);
+    }
+    body = Instructions(module, type.outputs, locals: locals);
+  }
+
+  /// Add a local variable to the function.
+  Local addLocal(ValueType type) {
+    Local local = Local(locals.length, type);
+    locals.add(local);
+    return local;
+  }
+
+  @override
+  void serialize(Serializer s) {
+    // Serialize locals internally first in order to compute the total size of
+    // the serialized data.
+    int paramCount = type.inputs.length;
+    int entries = 0;
+    for (int i = paramCount + 1; i <= locals.length; i++) {
+      if (i == locals.length || locals[i - 1].type != locals[i].type) entries++;
+    }
+    writeUnsigned(entries);
+    int start = paramCount;
+    for (int i = paramCount + 1; i <= locals.length; i++) {
+      if (i == locals.length || locals[i - 1].type != locals[i].type) {
+        writeUnsigned(i - start);
+        write(locals[i - 1].type);
+        start = i;
+      }
+    }
+
+    // Bundle locals and body
+    assert(body.isComplete);
+    s.writeUnsigned(data.length + body.data.length);
+    s.writeData(this);
+    s.writeData(body);
+  }
+
+  @override
+  String toString() => exportedName ?? "#$index";
+}
+
+/// A local variable defined in a function.
+class Local {
+  final int index;
+  final ValueType type;
+
+  Local(this.index, this.type);
+
+  @override
+  String toString() => "$index";
+}
+
+/// A table in a module.
+class Table implements Serializable {
+  final int index;
+  final int minSize;
+  final int? maxSize;
+  final List<BaseFunction?> elements;
+
+  Table(this.index, this.minSize, this.maxSize)
+      : elements = List.filled(minSize, null);
+
+  void setElement(int index, BaseFunction function) {
+    elements[index] = function;
+  }
+
+  @override
+  void serialize(Serializer s) {
+    s.writeByte(0x70); // funcref
+    if (maxSize == null) {
+      s.writeByte(0x00);
+      s.writeUnsigned(minSize);
+    } else {
+      s.writeByte(0x01);
+      s.writeUnsigned(minSize);
+      s.writeUnsigned(maxSize!);
+    }
+  }
+}
+
+/// A memory in a module.
+class Memory implements Serializable {
+  final int index;
+  final int minSize;
+  final int? maxSize;
+
+  Memory(this.index, this.minSize, [this.maxSize]);
+
+  @override
+  void serialize(Serializer s) {
+    if (maxSize == null) {
+      s.writeByte(0x00);
+      s.writeUnsigned(minSize);
+    } else {
+      s.writeByte(0x01);
+      s.writeUnsigned(minSize);
+      s.writeUnsigned(maxSize!);
+    }
+  }
+}
+
+/// A data segment in a module.
+class DataSegment implements Serializable {
+  final int index;
+  final BytesBuilder content;
+  final Memory? memory;
+  final int? offset;
+
+  DataSegment(this.index, Uint8List initialContent, this.memory, this.offset)
+      : content = BytesBuilder()..add(initialContent);
+
+  bool get isActive => memory != null;
+  bool get isPassive => memory == null;
+
+  int get length => content.length;
+
+  /// Append content to the data segment.
+  void append(Uint8List data) {
+    content.add(data);
+    assert(isPassive ||
+        offset! >= 0 && offset! + content.length <= memory!.minSize);
+  }
+
+  @override
+  void serialize(Serializer s) {
+    if (memory != null) {
+      // Active segment
+      if (memory!.index == 0) {
+        s.writeByte(0x00);
+      } else {
+        s.writeByte(0x02);
+        s.writeUnsigned(memory!.index);
+      }
+      s.writeByte(0x41); // i32.const
+      s.writeSigned(offset!);
+      s.writeByte(0x0B); // end
+    } else {
+      // Passive segment
+      s.writeByte(0x01);
+    }
+    s.writeUnsigned(content.length);
+    s.writeBytes(content.toBytes());
+  }
+}
+
+/// An (imported or defined) global variable in a module.
+abstract class Global {
+  final int index;
+  final GlobalType type;
+
+  Global(this.index, this.type);
+
+  @override
+  String toString() => "$index";
+}
+
+/// A global variable defined in the module.
+class DefinedGlobal extends Global implements Serializable {
+  final Instructions initializer;
+
+  DefinedGlobal(Module module, int index, GlobalType type)
+      : initializer =
+            Instructions(module, [type.type], isGlobalInitializer: true),
+        super(index, type);
+
+  @override
+  void serialize(Serializer s) {
+    assert(initializer.isComplete);
+    s.write(type);
+    s.writeData(initializer);
+  }
+}
+
+/// Any import (function or global).
+abstract class Import implements Serializable {
+  String get module;
+  String get name;
+}
+
+/// An imported function.
+class ImportedFunction extends BaseFunction implements Import {
+  final String module;
+  final String name;
+
+  ImportedFunction(this.module, this.name, int index, FunctionType type,
+      [String? functionName])
+      : super(index, type, functionName);
+
+  @override
+  void serialize(Serializer s) {
+    s.writeName(module);
+    s.writeName(name);
+    s.writeByte(0x00);
+    s.writeUnsigned(type.index);
+  }
+
+  @override
+  String toString() => "$module.$name";
+}
+
+/// An imported global variable.
+class ImportedGlobal extends Global implements Import {
+  final String module;
+  final String name;
+
+  ImportedGlobal(this.module, this.name, int index, GlobalType type)
+      : super(index, type);
+
+  @override
+  void serialize(Serializer s) {
+    s.writeName(module);
+    s.writeName(name);
+    s.writeByte(0x03);
+    s.write(type);
+  }
+}
+
+abstract class Export implements Serializable {
+  final String name;
+
+  Export(this.name);
+}
+
+class FunctionExport extends Export {
+  final BaseFunction function;
+
+  FunctionExport(String name, this.function) : super(name);
+
+  @override
+  void serialize(Serializer s) {
+    s.writeName(name);
+    s.writeByte(0x00);
+    s.writeUnsigned(function.index);
+  }
+}
+
+class GlobalExport extends Export {
+  final Global global;
+
+  GlobalExport(String name, this.global) : super(name);
+
+  @override
+  void serialize(Serializer s) {
+    s.writeName(name);
+    s.writeByte(0x03);
+    s.writeUnsigned(global.index);
+  }
+}
+
+abstract class Section with SerializerMixin implements Serializable {
+  final Module module;
+
+  Section(this.module);
+
+  void serialize(Serializer s) {
+    if (isNotEmpty) {
+      serializeContents();
+      s.writeByte(id);
+      s.writeUnsigned(data.length);
+      s.writeData(this, module.watchPoints);
+    }
+  }
+
+  int get id;
+
+  bool get isNotEmpty;
+
+  void serializeContents();
+}
+
+class TypeSection extends Section {
+  TypeSection(Module module) : super(module);
+
+  @override
+  int get id => 1;
+
+  @override
+  bool get isNotEmpty => module.defTypes.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeUnsigned(module.defTypes.length);
+    for (DefType defType in module.defTypes) {
+      defType.serializeDefinition(this);
+    }
+  }
+}
+
+class ImportSection extends Section {
+  ImportSection(Module module) : super(module);
+
+  @override
+  int get id => 2;
+
+  @override
+  bool get isNotEmpty => module.imports.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.imports.toList());
+  }
+}
+
+class FunctionSection extends Section {
+  FunctionSection(Module module) : super(module);
+
+  @override
+  int get id => 3;
+
+  @override
+  bool get isNotEmpty => module.definedFunctions.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeUnsigned(module.definedFunctions.length);
+    for (var function in module.definedFunctions) {
+      writeUnsigned(function.type.index);
+    }
+  }
+}
+
+class TableSection extends Section {
+  TableSection(Module module) : super(module);
+
+  @override
+  int get id => 4;
+
+  @override
+  bool get isNotEmpty => module.tables.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.tables);
+  }
+}
+
+class MemorySection extends Section {
+  MemorySection(Module module) : super(module);
+
+  @override
+  int get id => 5;
+
+  @override
+  bool get isNotEmpty => module.memories.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.memories);
+  }
+}
+
+class GlobalSection extends Section {
+  GlobalSection(Module module) : super(module);
+
+  @override
+  int get id => 6;
+
+  @override
+  bool get isNotEmpty => module.globals.whereType<DefinedGlobal>().isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.globals.whereType<DefinedGlobal>().toList());
+  }
+}
+
+class ExportSection extends Section {
+  ExportSection(Module module) : super(module);
+
+  @override
+  int get id => 7;
+
+  @override
+  bool get isNotEmpty => module.exports.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.exports);
+  }
+}
+
+class StartSection extends Section {
+  StartSection(Module module) : super(module);
+
+  @override
+  int get id => 8;
+
+  @override
+  bool get isNotEmpty => module.startFunction != null;
+
+  @override
+  void serializeContents() {
+    writeUnsigned(module.startFunction!.index);
+  }
+}
+
+class _Element implements Serializable {
+  final Table table;
+  final int startIndex;
+  final List<BaseFunction> entries = [];
+
+  _Element(this.table, this.startIndex);
+
+  @override
+  void serialize(Serializer s) {
+    s.writeUnsigned(table.index);
+    s.writeByte(0x41); // i32.const
+    s.writeSigned(startIndex);
+    s.writeByte(0x0B); // end
+    s.writeUnsigned(entries.length);
+    for (var entry in entries) {
+      s.writeUnsigned(entry.index);
+    }
+  }
+}
+
+class ElementSection extends Section {
+  ElementSection(Module module) : super(module);
+
+  @override
+  int get id => 9;
+
+  @override
+  bool get isNotEmpty =>
+      module.tables.any((table) => table.elements.any((e) => e != null));
+
+  @override
+  void serializeContents() {
+    // Group nonempty element entries into contiguous stretches and serialize
+    // each stretch as an element.
+    List<_Element> elements = [];
+    for (Table table in module.tables) {
+      _Element? current = null;
+      for (int i = 0; i < table.elements.length; i++) {
+        BaseFunction? function = table.elements[i];
+        if (function != null) {
+          if (current == null) {
+            current = _Element(table, i);
+            elements.add(current);
+          }
+          current.entries.add(function);
+        } else {
+          current = null;
+        }
+      }
+    }
+    writeList(elements);
+  }
+}
+
+class DataCountSection extends Section {
+  DataCountSection(Module module) : super(module);
+
+  @override
+  int get id => 12;
+
+  @override
+  bool get isNotEmpty => module.dataSegments.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeUnsigned(module.dataSegments.length);
+  }
+}
+
+class CodeSection extends Section {
+  CodeSection(Module module) : super(module);
+
+  @override
+  int get id => 10;
+
+  @override
+  bool get isNotEmpty => module.definedFunctions.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.definedFunctions.toList());
+  }
+}
+
+class DataSection extends Section {
+  DataSection(Module module) : super(module);
+
+  @override
+  int get id => 11;
+
+  @override
+  bool get isNotEmpty => module.dataSegments.isNotEmpty;
+
+  @override
+  void serializeContents() {
+    writeList(module.dataSegments);
+  }
+}
+
+abstract class CustomSection extends Section {
+  CustomSection(Module module) : super(module);
+
+  @override
+  int get id => 0;
+}
+
+class NameSection extends CustomSection {
+  NameSection(Module module) : super(module);
+
+  @override
+  bool get isNotEmpty => module.functionNameCount > 0;
+
+  @override
+  void serializeContents() {
+    writeName("name");
+    var functionNameSubsection = _NameSubsection();
+    functionNameSubsection.writeUnsigned(module.functionNameCount);
+    for (int i = 0; i < module.functions.length; i++) {
+      String? functionName = module.functions[i].functionName;
+      if (functionName != null) {
+        functionNameSubsection.writeUnsigned(i);
+        functionNameSubsection.writeName(functionName);
+      }
+    }
+    writeByte(1); // Function names subsection
+    writeUnsigned(functionNameSubsection.data.length);
+    writeData(functionNameSubsection);
+  }
+}
+
+class _NameSubsection with SerializerMixin {}
diff --git a/pkg/wasm_builder/lib/src/serialize.dart b/pkg/wasm_builder/lib/src/serialize.dart
new file mode 100644
index 0000000..007b6e1
--- /dev/null
+++ b/pkg/wasm_builder/lib/src/serialize.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2022, 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 'dart:collection';
+import 'dart:convert';
+import 'dart:typed_data';
+
+abstract class Serializer {
+  void writeByte(int byte);
+  void writeBytes(List<int> bytes);
+  void writeSigned(int value);
+  void writeUnsigned(int value);
+  void writeF32(double value);
+  void writeF64(double value);
+  void writeName(String name);
+  void write(Serializable object);
+  void writeList(List<Serializable> objects);
+  void writeData(Serializer chunk, [List<int>? watchPoints]);
+
+  Uint8List get data;
+}
+
+abstract class Serializable {
+  void serialize(Serializer s);
+}
+
+mixin SerializerMixin implements Serializer {
+  static bool traceEnabled = false;
+
+  // The prefix of `_data` up to `_index` contains the data serialized so far.
+  Uint8List _data = Uint8List(24);
+  int _index = 0;
+
+  // Stack traces or other serializers attached to byte positions within the
+  // chunk of data produced by this serializer.
+  late final SplayTreeMap<int, Object> _traces = SplayTreeMap();
+
+  void _ensure(int size) {
+    // Ensure space for at least `size` additional bytes.
+    if (_data.length < _index + size) {
+      int newLength = _data.length * 2;
+      while (newLength < _index + size) newLength *= 2;
+      _data = Uint8List(newLength)..setRange(0, _data.length, _data);
+    }
+  }
+
+  void _debugTrace(Object data) {
+    _traces[_index] ??= data;
+  }
+
+  void writeByte(int byte) {
+    if (traceEnabled) _debugTrace(StackTrace.current);
+    assert(byte == byte & 0xFF);
+    _ensure(1);
+    _data[_index++] = byte;
+  }
+
+  void writeBytes(List<int> bytes) {
+    if (traceEnabled) _debugTrace(StackTrace.current);
+    _ensure(bytes.length);
+    _data.setRange(_index, _index += bytes.length, bytes);
+  }
+
+  void writeSigned(int value) {
+    while (value < -0x40 || value >= 0x40) {
+      writeByte((value & 0x7F) | 0x80);
+      value >>= 7;
+    }
+    writeByte(value & 0x7F);
+  }
+
+  void writeUnsigned(int value) {
+    assert(value >= 0);
+    while (value >= 0x80) {
+      writeByte((value & 0x7F) | 0x80);
+      value >>= 7;
+    }
+    writeByte(value);
+  }
+
+  void writeF32(double value) {
+    // Get the binary representation of the F32.
+    List<int> bytes = Float32List.fromList([value]).buffer.asUint8List();
+    assert(bytes.length == 4);
+    if (Endian.host == Endian.big) bytes = bytes.reversed.toList();
+    writeBytes(bytes);
+  }
+
+  void writeF64(double value) {
+    // Get the binary representation of the F64.
+    List<int> bytes = Float64List.fromList([value]).buffer.asUint8List();
+    assert(bytes.length == 8);
+    if (Endian.host == Endian.big) bytes = bytes.reversed.toList();
+    writeBytes(bytes);
+  }
+
+  void writeName(String name) {
+    List<int> bytes = utf8.encode(name);
+    writeUnsigned(bytes.length);
+    writeBytes(bytes);
+  }
+
+  void write(Serializable object) {
+    object.serialize(this);
+  }
+
+  void writeList(List<Serializable> objects) {
+    writeUnsigned(objects.length);
+    for (int i = 0; i < objects.length; i++) write(objects[i]);
+  }
+
+  void writeData(Serializer chunk, [List<int>? watchPoints]) {
+    if (traceEnabled) _debugTrace(chunk);
+    if (watchPoints != null) {
+      for (int watchPoint in watchPoints) {
+        if (_index <= watchPoint && watchPoint < _index + chunk.data.length) {
+          int byteValue = chunk.data[watchPoint - _index];
+          Object trace = this;
+          int offset = watchPoint;
+          while (trace is SerializerMixin) {
+            int keyOffset = trace._traces.containsKey(offset)
+                ? offset
+                : trace._traces.lastKeyBefore(offset)!;
+            trace = trace._traces[keyOffset]!;
+            offset -= keyOffset;
+          }
+          String byte = byteValue.toRadixString(16).padLeft(2, '0');
+          print("Watch $watchPoint: 0x$byte\n$trace");
+        }
+      }
+    }
+    writeBytes(chunk.data);
+  }
+
+  Uint8List get data => Uint8List.sublistView(_data, 0, _index);
+}
diff --git a/pkg/wasm_builder/lib/src/types.dart b/pkg/wasm_builder/lib/src/types.dart
new file mode 100644
index 0000000..ecc8b1e
--- /dev/null
+++ b/pkg/wasm_builder/lib/src/types.dart
@@ -0,0 +1,657 @@
+// Copyright (c) 2022, 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 'serialize.dart';
+
+// Representations of all Wasm types.
+
+/// A *storage type*.
+abstract class StorageType implements Serializable {
+  /// Returns whether this type is a subtype of the [other] type, i.e. whether
+  /// it can be used as input where [other] is expected.
+  bool isSubtypeOf(StorageType other);
+
+  /// The *unpacked* form of this storage type, i.e. the *value type* to use
+  /// when reading/writing this storage type from/to memory.
+  ValueType get unpacked;
+
+  /// Whether this is a primitive (i.e. not reference) type.
+  bool get isPrimitive;
+
+  /// For primitive types: the size in bytes of a value of this type.
+  int get byteSize;
+}
+
+/// A *value type*.
+abstract class ValueType implements StorageType {
+  const ValueType();
+
+  @override
+  ValueType get unpacked => this;
+
+  @override
+  bool get isPrimitive => false;
+
+  @override
+  int get byteSize => throw "Size of non-primitive type $runtimeType";
+
+  /// Whether this type is nullable. Primitive types are never nullable.
+  bool get nullable => false;
+
+  /// If this exists in both a nullable and non-nullable version, return the
+  /// version with the given nullability.
+  ValueType withNullability(bool nullable) => this;
+
+  /// Whether this type is defaultable. Primitive types are always defaultable.
+  bool get defaultable => true;
+}
+
+enum NumTypeKind { i32, i64, f32, f64, v128 }
+
+/// A *number type* or *vector type*.
+class NumType extends ValueType {
+  final NumTypeKind kind;
+
+  const NumType._(this.kind);
+
+  /// The `i32` type.
+  static const i32 = NumType._(NumTypeKind.i32);
+
+  /// The `i64` type.
+  static const i64 = NumType._(NumTypeKind.i64);
+
+  /// The `f32` type.
+  static const f32 = NumType._(NumTypeKind.f32);
+
+  /// The `f64` type.
+  static const f64 = NumType._(NumTypeKind.f64);
+
+  /// The `v128` type.
+  static const v128 = NumType._(NumTypeKind.v128);
+
+  @override
+  bool isSubtypeOf(StorageType other) => this == other;
+
+  @override
+  bool get isPrimitive => true;
+
+  @override
+  int get byteSize {
+    switch (kind) {
+      case NumTypeKind.i32:
+      case NumTypeKind.f32:
+        return 4;
+      case NumTypeKind.i64:
+      case NumTypeKind.f64:
+        return 8;
+      case NumTypeKind.v128:
+        return 16;
+    }
+  }
+
+  @override
+  void serialize(Serializer s) {
+    switch (kind) {
+      case NumTypeKind.i32:
+        s.writeByte(0x7F);
+        break;
+      case NumTypeKind.i64:
+        s.writeByte(0x7E);
+        break;
+      case NumTypeKind.f32:
+        s.writeByte(0x7D);
+        break;
+      case NumTypeKind.f64:
+        s.writeByte(0x7C);
+        break;
+      case NumTypeKind.v128:
+        s.writeByte(0x7B);
+        break;
+    }
+  }
+
+  @override
+  String toString() {
+    switch (kind) {
+      case NumTypeKind.i32:
+        return "i32";
+      case NumTypeKind.i64:
+        return "i64";
+      case NumTypeKind.f32:
+        return "f32";
+      case NumTypeKind.f64:
+        return "f64";
+      case NumTypeKind.v128:
+        return "v128";
+    }
+  }
+}
+
+/// An RTT (runtime type) type.
+class Rtt extends ValueType {
+  final DefType defType;
+  final int? depth;
+
+  const Rtt(this.defType, [this.depth]);
+
+  @override
+  bool get defaultable => false;
+
+  @override
+  bool isSubtypeOf(StorageType other) =>
+      other is Rtt &&
+      defType == other.defType &&
+      (other.depth == null || depth == other.depth);
+
+  @override
+  void serialize(Serializer s) {
+    if (depth != null) {
+      s.writeByte(0x69);
+      s.writeUnsigned(depth!);
+    } else {
+      s.writeByte(0x68);
+    }
+    s.writeSigned(defType.index);
+  }
+
+  @override
+  String toString() => depth == null ? "rtt $defType" : "rtt $depth $defType";
+
+  @override
+  bool operator ==(Object other) =>
+      other is Rtt && other.defType == defType && other.depth == depth;
+
+  @override
+  int get hashCode => defType.hashCode * (3 + (depth ?? -3) * 2);
+}
+
+/// A *reference type*.
+class RefType extends ValueType {
+  /// The *heap type* of this reference type.
+  final HeapType heapType;
+
+  /// The nullability of this reference type.
+  final bool nullable;
+
+  RefType(this.heapType, {bool? nullable})
+      : this.nullable = nullable ??
+            heapType.nullableByDefault ??
+            (throw "Unspecified nullability");
+
+  const RefType._(this.heapType, this.nullable);
+
+  /// A (possibly nullable) reference to the `any` heap type.
+  const RefType.any({bool nullable = AnyHeapType.defaultNullability})
+      : this._(HeapType.any, nullable);
+
+  /// A (possibly nullable) reference to the `eq` heap type.
+  const RefType.eq({bool nullable = EqHeapType.defaultNullability})
+      : this._(HeapType.eq, nullable);
+
+  /// A (possibly nullable) reference to the `func` heap type.
+  const RefType.func({bool nullable = FuncHeapType.defaultNullability})
+      : this._(HeapType.func, nullable);
+
+  /// A (possibly nullable) reference to the `data` heap type.
+  const RefType.data({bool nullable = DataHeapType.defaultNullability})
+      : this._(HeapType.data, nullable);
+
+  /// A (possibly nullable) reference to the `i31` heap type.
+  const RefType.i31({bool nullable = I31HeapType.defaultNullability})
+      : this._(HeapType.i31, nullable);
+
+  /// A (possibly nullable) reference to the `extern` heap type.
+  const RefType.extern({bool nullable = ExternHeapType.defaultNullability})
+      : this._(HeapType.extern, nullable);
+
+  /// A (possibly nullable) reference to a custom heap type.
+  RefType.def(DefType defType, {required bool nullable})
+      : this(defType, nullable: nullable);
+
+  @override
+  ValueType withNullability(bool nullable) =>
+      nullable == this.nullable ? this : RefType(heapType, nullable: nullable);
+
+  @override
+  bool get defaultable => nullable;
+
+  @override
+  bool isSubtypeOf(StorageType other) {
+    if (other is! RefType) return false;
+    if (nullable && !other.nullable) return false;
+    return heapType.isSubtypeOf(other.heapType);
+  }
+
+  @override
+  void serialize(Serializer s) {
+    if (nullable != heapType.nullableByDefault) {
+      s.writeByte(nullable ? 0x6C : 0x6B);
+    }
+    s.write(heapType);
+  }
+
+  @override
+  String toString() {
+    if (nullable == heapType.nullableByDefault) return "${heapType}ref";
+    return "ref${nullable ? " null " : " "}${heapType}";
+  }
+
+  @override
+  bool operator ==(Object other) =>
+      other is RefType &&
+      other.heapType == heapType &&
+      other.nullable == nullable;
+
+  @override
+  int get hashCode => heapType.hashCode * (nullable ? -1 : 1);
+}
+
+/// A *heap type*.
+abstract class HeapType implements Serializable {
+  const HeapType();
+
+  /// The `any` heap type.
+  static const any = AnyHeapType._();
+
+  /// The `eq` heap type.
+  static const eq = EqHeapType._();
+
+  /// The `func` heap type.
+  static const func = FuncHeapType._();
+
+  /// The `data` heap type.
+  static const data = DataHeapType._();
+
+  /// The `i31` heap type.
+  static const i31 = I31HeapType._();
+
+  /// The `extern` heap type.
+  static const extern = ExternHeapType._();
+
+  /// Whether this heap type is nullable by default, i.e. when written with the
+  /// -`ref` shorthand. A `null` value here means the heap type has no default
+  /// nullability, so the nullability of a reference has to be specified
+  /// explicitly.
+  bool? get nullableByDefault;
+
+  /// Whether this heap type is a declared subtype of the other heap type.
+  bool isSubtypeOf(HeapType other);
+
+  /// Whether this heap type is a structural subtype of the other heap type.
+  bool isStructuralSubtypeOf(HeapType other) => isSubtypeOf(other);
+}
+
+/// The `any` heap type.
+class AnyHeapType extends HeapType {
+  const AnyHeapType._();
+
+  static const defaultNullability = true;
+
+  @override
+  bool? get nullableByDefault => defaultNullability;
+
+  @override
+  bool isSubtypeOf(HeapType other) => other == HeapType.any;
+
+  @override
+  void serialize(Serializer s) => s.writeByte(0x6E);
+
+  @override
+  String toString() => "any";
+}
+
+/// The `eq` heap type.
+class EqHeapType extends HeapType {
+  const EqHeapType._();
+
+  static const defaultNullability = true;
+
+  @override
+  bool? get nullableByDefault => defaultNullability;
+
+  @override
+  bool isSubtypeOf(HeapType other) =>
+      other == HeapType.any || other == HeapType.eq;
+
+  @override
+  void serialize(Serializer s) => s.writeByte(0x6D);
+
+  @override
+  String toString() => "eq";
+}
+
+/// The `func` heap type.
+class FuncHeapType extends HeapType {
+  const FuncHeapType._();
+
+  static const defaultNullability = true;
+
+  @override
+  bool? get nullableByDefault => defaultNullability;
+
+  @override
+  bool isSubtypeOf(HeapType other) =>
+      other == HeapType.any || other == HeapType.func;
+
+  @override
+  void serialize(Serializer s) => s.writeByte(0x70);
+
+  @override
+  String toString() => "func";
+}
+
+/// The `data` heap type.
+class DataHeapType extends HeapType {
+  const DataHeapType._();
+
+  static const defaultNullability = false;
+
+  @override
+  bool? get nullableByDefault => defaultNullability;
+
+  @override
+  bool isSubtypeOf(HeapType other) =>
+      other == HeapType.any || other == HeapType.eq || other == HeapType.data;
+
+  @override
+  void serialize(Serializer s) => s.writeByte(0x67);
+
+  @override
+  String toString() => "data";
+}
+
+/// The `i31` heap type.
+class I31HeapType extends HeapType {
+  const I31HeapType._();
+
+  static const defaultNullability = false;
+
+  @override
+  bool? get nullableByDefault => defaultNullability;
+
+  @override
+  bool isSubtypeOf(HeapType other) =>
+      other == HeapType.any || other == HeapType.eq || other == HeapType.i31;
+
+  @override
+  void serialize(Serializer s) => s.writeByte(0x6A);
+
+  @override
+  String toString() => "i31";
+}
+
+/// The `extern` heap type.
+class ExternHeapType extends HeapType {
+  const ExternHeapType._();
+
+  static const defaultNullability = true;
+
+  @override
+  bool? get nullableByDefault => defaultNullability;
+
+  @override
+  bool isSubtypeOf(HeapType other) =>
+      other == HeapType.any || other == HeapType.extern;
+
+  @override
+  void serialize(Serializer s) => s.writeByte(0x6F);
+
+  @override
+  String toString() => "extern";
+}
+
+/// A custom heap type.
+abstract class DefType extends HeapType {
+  int? _index;
+
+  /// For nominal types: the declared supertype of this heap type.
+  final HeapType? superType;
+
+  /// The length of the supertype chain of this heap type.
+  final int depth;
+
+  DefType({this.superType})
+      : depth = superType is DefType ? superType.depth + 1 : 0;
+
+  int get index => _index ?? (throw "$runtimeType $this not added to module");
+  set index(int i) => _index = i;
+
+  bool get hasSuperType => superType != null;
+
+  @override
+  bool? get nullableByDefault => null;
+
+  @override
+  bool isSubtypeOf(HeapType other) {
+    if (this == other) return true;
+    if (hasSuperType) {
+      return superType!.isSubtypeOf(other);
+    }
+    return isStructuralSubtypeOf(other);
+  }
+
+  @override
+  void serialize(Serializer s) => s.writeSigned(index);
+
+  void serializeDefinition(Serializer s);
+}
+
+/// A custom function type.
+class FunctionType extends DefType {
+  final List<ValueType> inputs;
+  final List<ValueType> outputs;
+
+  FunctionType(this.inputs, this.outputs, {HeapType? superType})
+      : super(superType: superType);
+
+  @override
+  bool isStructuralSubtypeOf(HeapType other) {
+    if (other == HeapType.any || other == HeapType.func) return true;
+    if (other is! FunctionType) return false;
+    if (inputs.length != other.inputs.length) return false;
+    if (outputs.length != other.outputs.length) return false;
+    for (int i = 0; i < inputs.length; i++) {
+      // Inputs are contravariant.
+      if (!other.inputs[i].isSubtypeOf(inputs[i])) return false;
+    }
+    for (int i = 0; i < outputs.length; i++) {
+      // Outputs are covariant.
+      if (!outputs[i].isSubtypeOf(other.outputs[i])) return false;
+    }
+    return true;
+  }
+
+  @override
+  void serializeDefinition(Serializer s) {
+    s.writeByte(hasSuperType ? 0x5D : 0x60);
+    s.writeList(inputs);
+    s.writeList(outputs);
+    if (hasSuperType) {
+      assert(isStructuralSubtypeOf(superType!));
+      s.write(superType!);
+    }
+  }
+
+  @override
+  String toString() => "(${inputs.join(", ")}) -> (${outputs.join(", ")})";
+}
+
+/// A subtype of the `data` heap type, i.e. `struct` or `array`.
+abstract class DataType extends DefType {
+  final String name;
+
+  DataType(this.name, {HeapType? superType}) : super(superType: superType);
+
+  @override
+  String toString() => name;
+}
+
+/// A custom `struct` type.
+class StructType extends DataType {
+  final List<FieldType> fields = [];
+
+  StructType(String name, {Iterable<FieldType>? fields, HeapType? superType})
+      : super(name, superType: superType) {
+    if (fields != null) this.fields.addAll(fields);
+  }
+
+  @override
+  bool isStructuralSubtypeOf(HeapType other) {
+    if (other == HeapType.any ||
+        other == HeapType.eq ||
+        other == HeapType.data) {
+      return true;
+    }
+    if (other is! StructType) return false;
+    if (fields.length < other.fields.length) return false;
+    for (int i = 0; i < other.fields.length; i++) {
+      if (!fields[i].isSubtypeOf(other.fields[i])) return false;
+    }
+    return true;
+  }
+
+  @override
+  void serializeDefinition(Serializer s) {
+    s.writeByte(hasSuperType ? 0x5C : 0x5F);
+    s.writeList(fields);
+    if (hasSuperType) {
+      assert(isStructuralSubtypeOf(superType!));
+      s.write(superType!);
+    }
+  }
+}
+
+/// A custom `array` type.
+class ArrayType extends DataType {
+  late final FieldType elementType;
+
+  ArrayType(String name, {FieldType? elementType, HeapType? superType})
+      : super(name, superType: superType) {
+    if (elementType != null) this.elementType = elementType;
+  }
+
+  @override
+  bool isStructuralSubtypeOf(HeapType other) {
+    if (other == HeapType.any ||
+        other == HeapType.eq ||
+        other == HeapType.data) {
+      return true;
+    }
+    if (other is! ArrayType) return false;
+    return elementType.isSubtypeOf(other.elementType);
+  }
+
+  @override
+  void serializeDefinition(Serializer s) {
+    s.writeByte(hasSuperType ? 0x5B : 0x5E);
+    s.write(elementType);
+    if (hasSuperType) {
+      assert(isStructuralSubtypeOf(superType!));
+      s.write(superType!);
+    }
+  }
+}
+
+class _WithMutability<T extends StorageType> implements Serializable {
+  final T type;
+  final bool mutable;
+
+  _WithMutability(this.type, this.mutable);
+
+  @override
+  void serialize(Serializer s) {
+    s.write(type);
+    s.writeByte(mutable ? 0x01 : 0x00);
+  }
+
+  @override
+  String toString() => "${mutable ? "var " : "const "}$type";
+}
+
+/// A type for a global.
+///
+/// It consists of a type and a mutability.
+class GlobalType extends _WithMutability<ValueType> {
+  GlobalType(ValueType type, {bool mutable = true}) : super(type, mutable);
+}
+
+/// A type for a struct field or an array element.
+///
+/// It consists of a type and a mutability.
+class FieldType extends _WithMutability<StorageType> {
+  FieldType(StorageType type, {bool mutable = true}) : super(type, mutable);
+
+  /// The `i8` storage type as a field type.
+  FieldType.i8({bool mutable: true}) : this(PackedType.i8, mutable: mutable);
+
+  /// The `i16` storage type as a field type.
+  FieldType.i16({bool mutable: true}) : this(PackedType.i16, mutable: mutable);
+
+  bool isSubtypeOf(FieldType other) {
+    if (mutable != other.mutable) return false;
+    if (mutable) {
+      // Mutable fields are invariant.
+      return type == other.type;
+    } else {
+      // Immutable fields are covariant.
+      return type.isSubtypeOf(other.type);
+    }
+  }
+}
+
+enum PackedTypeKind { i8, i16 }
+
+/// A *packed type*, i.e. a storage type that only exists in memory.
+class PackedType implements StorageType {
+  final PackedTypeKind kind;
+
+  const PackedType._(this.kind);
+
+  /// The `i8` storage type.
+  static const i8 = PackedType._(PackedTypeKind.i8);
+
+  /// The `i16` storage type.
+  static const i16 = PackedType._(PackedTypeKind.i16);
+
+  @override
+  ValueType get unpacked => NumType.i32;
+
+  @override
+  bool isSubtypeOf(StorageType other) => this == other;
+
+  @override
+  bool get isPrimitive => true;
+
+  @override
+  int get byteSize {
+    switch (kind) {
+      case PackedTypeKind.i8:
+        return 1;
+      case PackedTypeKind.i16:
+        return 2;
+    }
+  }
+
+  @override
+  void serialize(Serializer s) {
+    switch (kind) {
+      case PackedTypeKind.i8:
+        s.writeByte(0x7A);
+        break;
+      case PackedTypeKind.i16:
+        s.writeByte(0x79);
+        break;
+    }
+  }
+
+  @override
+  String toString() {
+    switch (kind) {
+      case PackedTypeKind.i8:
+        return "i8";
+      case PackedTypeKind.i16:
+        return "i16";
+    }
+  }
+}
diff --git a/pkg/wasm_builder/lib/wasm_builder.dart b/pkg/wasm_builder/lib/wasm_builder.dart
new file mode 100644
index 0000000..8bf1b98
--- /dev/null
+++ b/pkg/wasm_builder/lib/wasm_builder.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2022, 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.
+
+export 'src/module.dart'
+    show
+        DataSegment,
+        DefinedFunction,
+        DefinedGlobal,
+        BaseFunction,
+        Global,
+        ImportedFunction,
+        ImportedGlobal,
+        Local,
+        Memory,
+        Module,
+        Table;
+export 'src/types.dart'
+    show
+        ArrayType,
+        DataType,
+        DefType,
+        FieldType,
+        FunctionType,
+        GlobalType,
+        HeapType,
+        NumType,
+        PackedType,
+        RefType,
+        Rtt,
+        StorageType,
+        StructType,
+        ValueType;
+export 'src/instructions.dart' show Instructions, Label, ValidationError;
diff --git a/pkg/wasm_builder/pubspec.yaml b/pkg/wasm_builder/pubspec.yaml
new file mode 100644
index 0000000..af4d545
--- /dev/null
+++ b/pkg/wasm_builder/pubspec.yaml
@@ -0,0 +1,9 @@
+name: wasm_builder
+# This package is not intended for consumption on pub.dev. DO NOT publish.
+publish_to: none
+description: Generate binary Wasm modules
+
+environment:
+  sdk: '>=2.12.0'
+
+dependencies:
diff --git a/sdk/bin/dart2wasm b/sdk/bin/dart2wasm
new file mode 100755
index 0000000..893fcda
--- /dev/null
+++ b/sdk/bin/dart2wasm
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+# Copyright (c) 2022, 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.
+
+# Run dart2wasm on the Dart VM. This script assumes the Dart repo's
+# directory structure.
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+SDK_ARG="--dart-sdk=$SDK_DIR"
+
+DART="$BIN_DIR/dart"
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+case $0 in
+  *_developer)
+    EXTRA_VM_OPTIONS+=('--enable_asserts')
+    ;;
+esac
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+DART_ROOT="$(cd "${SDK_DIR}/.." ; pwd -P)"
+
+DART2WASM_COMPILER="$DART_ROOT/pkg/dart2wasm/bin/dart2wasm.dart"
+
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DART2WASM_COMPILER" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dart2wasm_developer b/sdk/bin/dart2wasm_developer
new file mode 100755
index 0000000..aabf8ea
--- /dev/null
+++ b/sdk/bin/dart2wasm_developer
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# Copyright (c) 2022, 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.
+
+. ${BASH_SOURCE%_developer}
diff --git a/sdk/lib/_internal/vm/lib/compact_hash.dart b/sdk/lib/_internal/vm/lib/compact_hash.dart
index 6ed0c80..fa4b32d 100644
--- a/sdk/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk/lib/_internal/vm/lib/compact_hash.dart
@@ -624,6 +624,9 @@
   V? operator [](Object? o) => _validKey(o) ? super[o] : null;
   V? remove(Object? o) => _validKey(o) ? super.remove(o) : null;
 
+  @pragma("wasm:entry-point")
+  void operator []=(K key, V value);
+
   _CompactLinkedCustomHashMap(this._equality, this._hasher, validKey)
       : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test,
         super(_HashBase._INITIAL_INDEX_SIZE);
diff --git a/sdk/lib/_internal/vm/lib/typed_data_patch.dart b/sdk/lib/_internal/vm/lib/typed_data_patch.dart
index 37587c7..68c63b1 100644
--- a/sdk/lib/_internal/vm/lib/typed_data_patch.dart
+++ b/sdk/lib/_internal/vm/lib/typed_data_patch.dart
@@ -2228,6 +2228,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint8List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
@@ -2281,6 +2282,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint8ClampedList extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
     implements Uint8ClampedList {
@@ -2334,6 +2336,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int16List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Int16List>
     implements Int16List {
@@ -2407,6 +2410,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint16List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Uint16List>
     implements Uint16List {
@@ -2480,6 +2484,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int32List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Int32List>
     implements Int32List {
@@ -2540,6 +2545,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint32List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Uint32List>
     implements Uint32List {
@@ -2600,6 +2606,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int64List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Int64List>
     implements Int64List {
@@ -2660,6 +2667,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint64List extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Uint64List>
     implements Uint64List {
@@ -2720,6 +2728,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Float32List extends _TypedList
     with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
     implements Float32List {
@@ -2781,6 +2790,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Float64List extends _TypedList
     with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
     implements Float64List {
@@ -3040,6 +3050,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _ExternalUint8Array extends _TypedList
     with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
@@ -4123,6 +4134,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int8ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Int8List>
     implements Int8List {
@@ -4164,6 +4176,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint8ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
@@ -4205,6 +4218,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint8ClampedArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
     implements Uint8ClampedList {
@@ -4246,6 +4260,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int16ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Int16List>
     implements Int16List {
@@ -4300,6 +4315,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint16ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Uint16List>
     implements Uint16List {
@@ -4355,6 +4371,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int32ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Int32List>
     implements Int32List {
@@ -4396,6 +4413,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint32ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Uint32List>
     implements Uint32List {
@@ -4437,6 +4455,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Int64ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Int64List>
     implements Int64List {
@@ -4478,6 +4497,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Uint64ArrayView extends _TypedListView
     with _IntListMixin, _TypedIntListMixin<Uint64List>
     implements Uint64List {
@@ -4519,6 +4539,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Float32ArrayView extends _TypedListView
     with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
     implements Float32List {
@@ -4560,6 +4581,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _Float64ArrayView extends _TypedListView
     with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
     implements Float64List {
@@ -4718,6 +4740,7 @@
 }
 
 @pragma("vm:entry-point")
+@pragma("wasm:entry-point")
 class _ByteDataView implements ByteData {
   @pragma("vm:recognized", "other")
   @pragma("vm:exact-result-type", _ByteDataView)
diff --git a/sdk/lib/_internal/wasm/lib/bool.dart b/sdk/lib/_internal/wasm/lib/bool.dart
new file mode 100644
index 0000000..929e519
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/bool.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, 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.
+
+@pragma("wasm:entry-point")
+class _BoxedBool implements bool {
+  // A boxed bool contains an unboxed bool.
+  @pragma("wasm:entry-point")
+  bool value = false;
+
+  @override
+  bool operator ==(Object other) {
+    return other is bool
+        ? this == other // Intrinsic ==
+        : false;
+  }
+
+  bool operator &(bool other) => this & other; // Intrinsic &
+  bool operator ^(bool other) => this ^ other; // Intrinsic ^
+  bool operator |(bool other) => this | other; // Intrinsic |
+}
diff --git a/sdk/lib/_internal/wasm/lib/class_id.dart b/sdk/lib/_internal/wasm/lib/class_id.dart
new file mode 100644
index 0000000..e650509
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/class_id.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2022, 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.
+
+// part of "internal_patch.dart";
+
+@pragma("wasm:entry-point")
+class ClassID {
+  external static int getID(Object value);
+
+  @pragma("wasm:class-id", "dart.typed_data#_ExternalUint8Array")
+  external static int get cidExternalUint8Array;
+  @pragma("wasm:class-id", "dart.typed_data#_Uint8List")
+  external static int get cidUint8Array;
+  @pragma("wasm:class-id", "dart.typed_data#_Uint8ArrayView")
+  external static int get cidUint8ArrayView;
+
+  // Dummy, only used by VM-specific hash table code.
+  static final int numPredefinedCids = 1;
+}
diff --git a/sdk/lib/_internal/wasm/lib/core_patch.dart b/sdk/lib/_internal/wasm/lib/core_patch.dart
new file mode 100644
index 0000000..64b7d9d
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/core_patch.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, 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 "dart:_internal" show patch;
+
+import "dart:_internal"
+    show
+        allocateOneByteString,
+        allocateTwoByteString,
+        CodeUnits,
+        copyRangeFromUint8ListToOneByteString,
+        doubleToIntBits,
+        EfficientLengthIterable,
+        FixedLengthListMixin,
+        IterableElementError,
+        ListIterator,
+        Lists,
+        mix64,
+        POWERS_OF_TEN,
+        SubListIterable,
+        UnmodifiableListMixin,
+        has63BitSmis,
+        makeFixedListUnmodifiable,
+        makeListFixedLength,
+        patch,
+        unsafeCast,
+        writeIntoOneByteString,
+        writeIntoTwoByteString;
+
+import "dart:collection"
+    show
+        HashMap,
+        IterableBase,
+        LinkedHashMap,
+        LinkedList,
+        LinkedListEntry,
+        ListBase,
+        MapBase,
+        Maps,
+        UnmodifiableMapBase,
+        UnmodifiableMapView;
+
+import 'dart:math' show Random;
+
+import "dart:typed_data"
+    show Endian, Uint8List, Int64List, Uint16List, Uint32List;
+
+import 'dart:wasm';
+
+typedef _Smi = int; // For compatibility with VM patch files
diff --git a/sdk/lib/_internal/wasm/lib/date_patch.dart b/sdk/lib/_internal/wasm/lib/date_patch.dart
new file mode 100644
index 0000000..f2f0672
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/date_patch.dart
@@ -0,0 +1,542 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+// This file is identical to the VM `date_patch.dart` except for the
+// implementation of `_getCurrentMicros` and the `_jsDateNow` import.
+// TODO(askesc): Share this file with the VM when the patching mechanism gains
+// support for patching an external member from a patch in a separate patch.
+
+@pragma("wasm:import", "Date.now")
+external double _jsDateNow();
+
+// VM implementation of DateTime.
+@patch
+class DateTime {
+  // Natives.
+  // The natives have been moved up here to work around Issue 10401.
+  @pragma("vm:external-name", "DateTime_currentTimeMicros")
+  static int _getCurrentMicros() =>
+      (_jsDateNow() * Duration.microsecondsPerMillisecond).toInt();
+
+  @pragma("vm:external-name", "DateTime_timeZoneName")
+  external static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch);
+
+  @pragma("vm:external-name", "DateTime_timeZoneOffsetInSeconds")
+  external static int _timeZoneOffsetInSecondsForClampedSeconds(
+      int secondsSinceEpoch);
+
+  // Daylight-savings independent adjustment for the local time zone.
+  @pragma("vm:external-name", "DateTime_localTimeZoneAdjustmentInSeconds")
+  external static int _localTimeZoneAdjustmentInSeconds();
+
+  static const _MICROSECOND_INDEX = 0;
+  static const _MILLISECOND_INDEX = 1;
+  static const _SECOND_INDEX = 2;
+  static const _MINUTE_INDEX = 3;
+  static const _HOUR_INDEX = 4;
+  static const _DAY_INDEX = 5;
+  static const _WEEKDAY_INDEX = 6;
+  static const _MONTH_INDEX = 7;
+  static const _YEAR_INDEX = 8;
+
+  List<int>? __parts;
+
+  @patch
+  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+      {bool isUtc: false})
+      : this._withValue(
+            _validateMilliseconds(millisecondsSinceEpoch) *
+                Duration.microsecondsPerMillisecond,
+            isUtc: isUtc);
+
+  @patch
+  DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+      {bool isUtc: false})
+      : this._withValue(microsecondsSinceEpoch, isUtc: isUtc);
+
+  @patch
+  DateTime._internal(int year, int month, int day, int hour, int minute,
+      int second, int millisecond, int microsecond, bool isUtc)
+      : this.isUtc = isUtc,
+        this._value = _brokenDownDateToValue(year, month, day, hour, minute,
+                second, millisecond, microsecond, isUtc) ??
+            -1 {
+    if (_value == -1) throw new ArgumentError();
+    if (isUtc == null) throw new ArgumentError();
+  }
+
+  static int _validateMilliseconds(int millisecondsSinceEpoch) =>
+      RangeError.checkValueInInterval(
+          millisecondsSinceEpoch,
+          -_maxMillisecondsSinceEpoch,
+          _maxMillisecondsSinceEpoch,
+          "millisecondsSinceEpoch");
+
+  @patch
+  DateTime._now()
+      : isUtc = false,
+        _value = _getCurrentMicros();
+
+  @patch
+  String get timeZoneName {
+    if (isUtc) return "UTC";
+    return _timeZoneName(microsecondsSinceEpoch);
+  }
+
+  @patch
+  Duration get timeZoneOffset {
+    if (isUtc) return new Duration();
+    int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch);
+    return new Duration(seconds: offsetInSeconds);
+  }
+
+  @patch
+  bool operator ==(dynamic other) =>
+      other is DateTime &&
+      _value == other.microsecondsSinceEpoch &&
+      isUtc == other.isUtc;
+
+  @patch
+  bool isBefore(DateTime other) => _value < other.microsecondsSinceEpoch;
+
+  @patch
+  bool isAfter(DateTime other) => _value > other.microsecondsSinceEpoch;
+
+  @patch
+  bool isAtSameMomentAs(DateTime other) =>
+      _value == other.microsecondsSinceEpoch;
+
+  @patch
+  int compareTo(DateTime other) =>
+      _value.compareTo(other.microsecondsSinceEpoch);
+
+  /** The first list contains the days until each month in non-leap years. The
+    * second list contains the days in leap years. */
+  static const List<List<int>> _DAYS_UNTIL_MONTH = const [
+    const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
+    const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
+  ];
+
+  static List<int> _computeUpperPart(int localMicros) {
+    const int DAYS_IN_4_YEARS = 4 * 365 + 1;
+    const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
+    const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
+    const int DAYS_1970_TO_2000 = 30 * 365 + 7;
+    const int DAYS_OFFSET =
+        1000 * DAYS_IN_400_YEARS + 5 * DAYS_IN_400_YEARS - DAYS_1970_TO_2000;
+    const int YEARS_OFFSET = 400000;
+
+    int resultYear = 0;
+    int resultMonth = 0;
+    int resultDay = 0;
+
+    // Always round down.
+    final int daysSince1970 =
+        _flooredDivision(localMicros, Duration.microsecondsPerDay);
+    int days = daysSince1970;
+    days += DAYS_OFFSET;
+    resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET;
+    days = unsafeCast<int>(days.remainder(DAYS_IN_400_YEARS));
+    days--;
+    int yd1 = days ~/ DAYS_IN_100_YEARS;
+    days = unsafeCast<int>(days.remainder(DAYS_IN_100_YEARS));
+    resultYear += 100 * yd1;
+    days++;
+    int yd2 = days ~/ DAYS_IN_4_YEARS;
+    days = unsafeCast<int>(days.remainder(DAYS_IN_4_YEARS));
+    resultYear += 4 * yd2;
+    days--;
+    int yd3 = days ~/ 365;
+    days = unsafeCast<int>(days.remainder(365));
+    resultYear += yd3;
+
+    bool isLeap = (yd1 == 0 || yd2 != 0) && yd3 == 0;
+    if (isLeap) days++;
+
+    List<int> daysUntilMonth = _DAYS_UNTIL_MONTH[isLeap ? 1 : 0];
+    for (resultMonth = 12;
+        daysUntilMonth[resultMonth - 1] > days;
+        resultMonth--) {
+      // Do nothing.
+    }
+    resultDay = days - daysUntilMonth[resultMonth - 1] + 1;
+
+    int resultMicrosecond = localMicros % Duration.microsecondsPerMillisecond;
+    int resultMillisecond =
+        _flooredDivision(localMicros, Duration.microsecondsPerMillisecond) %
+            Duration.millisecondsPerSecond;
+    int resultSecond =
+        _flooredDivision(localMicros, Duration.microsecondsPerSecond) %
+            Duration.secondsPerMinute;
+
+    int resultMinute =
+        _flooredDivision(localMicros, Duration.microsecondsPerMinute);
+    resultMinute %= Duration.minutesPerHour;
+
+    int resultHour =
+        _flooredDivision(localMicros, Duration.microsecondsPerHour);
+    resultHour %= Duration.hoursPerDay;
+
+    // In accordance with ISO 8601 a week
+    // starts with Monday. Monday has the value 1 up to Sunday with 7.
+    // 1970-1-1 was a Thursday.
+    int resultWeekday = ((daysSince1970 + DateTime.thursday - DateTime.monday) %
+            DateTime.daysPerWeek) +
+        DateTime.monday;
+
+    List<int> list = new List<int>.filled(_YEAR_INDEX + 1, 0);
+    list[_MICROSECOND_INDEX] = resultMicrosecond;
+    list[_MILLISECOND_INDEX] = resultMillisecond;
+    list[_SECOND_INDEX] = resultSecond;
+    list[_MINUTE_INDEX] = resultMinute;
+    list[_HOUR_INDEX] = resultHour;
+    list[_DAY_INDEX] = resultDay;
+    list[_WEEKDAY_INDEX] = resultWeekday;
+    list[_MONTH_INDEX] = resultMonth;
+    list[_YEAR_INDEX] = resultYear;
+    return list;
+  }
+
+  List<int> get _parts {
+    return __parts ??= _computeUpperPart(_localDateInUtcMicros);
+  }
+
+  @patch
+  DateTime add(Duration duration) {
+    return new DateTime._withValue(_value + duration.inMicroseconds,
+        isUtc: isUtc);
+  }
+
+  @patch
+  DateTime subtract(Duration duration) {
+    return new DateTime._withValue(_value - duration.inMicroseconds,
+        isUtc: isUtc);
+  }
+
+  @patch
+  Duration difference(DateTime other) {
+    return new Duration(microseconds: _value - other.microsecondsSinceEpoch);
+  }
+
+  @patch
+  int get millisecondsSinceEpoch =>
+      _value ~/ Duration.microsecondsPerMillisecond;
+
+  @patch
+  int get microsecondsSinceEpoch => _value;
+
+  @patch
+  int get microsecond => _parts[_MICROSECOND_INDEX];
+
+  @patch
+  int get millisecond => _parts[_MILLISECOND_INDEX];
+
+  @patch
+  int get second => _parts[_SECOND_INDEX];
+
+  @patch
+  int get minute => _parts[_MINUTE_INDEX];
+
+  @patch
+  int get hour => _parts[_HOUR_INDEX];
+
+  @patch
+  int get day => _parts[_DAY_INDEX];
+
+  @patch
+  int get weekday => _parts[_WEEKDAY_INDEX];
+
+  @patch
+  int get month => _parts[_MONTH_INDEX];
+
+  @patch
+  int get year => _parts[_YEAR_INDEX];
+
+  /**
+   * Returns the amount of microseconds in UTC that represent the same values
+   * as [this].
+   *
+   * Say `t` is the result of this function, then
+   * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`,
+   * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`,
+   * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`,
+   * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`,
+   * * ...
+   *
+   * Daylight savings is computed as if the date was computed in [1970..2037].
+   * If [this] lies outside this range then it is a year with similar
+   * properties (leap year, weekdays) is used instead.
+   */
+  int get _localDateInUtcMicros {
+    int micros = _value;
+    if (isUtc) return micros;
+    int offset =
+        _timeZoneOffsetInSeconds(micros) * Duration.microsecondsPerSecond;
+    return micros + offset;
+  }
+
+  static int _flooredDivision(int a, int b) {
+    return (a - (a < 0 ? b - 1 : 0)) ~/ b;
+  }
+
+  // Returns the days since 1970 for the start of the given [year].
+  // [year] may be before epoch.
+  static int _dayFromYear(int year) {
+    return 365 * (year - 1970) +
+        _flooredDivision(year - 1969, 4) -
+        _flooredDivision(year - 1901, 100) +
+        _flooredDivision(year - 1601, 400);
+  }
+
+  static bool _isLeapYear(int y) {
+    // (y % 16 == 0) matches multiples of 400, and is faster than % 400.
+    return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0));
+  }
+
+  /// Converts the given broken down date to microseconds.
+  @patch
+  static int? _brokenDownDateToValue(int year, int month, int day, int hour,
+      int minute, int second, int millisecond, int microsecond, bool isUtc) {
+    // Simplify calculations by working with zero-based month.
+    --month;
+    // Deal with under and overflow.
+    if (month >= 12) {
+      year += month ~/ 12;
+      month = month % 12;
+    } else if (month < 0) {
+      int realMonth = month % 12;
+      year += (month - realMonth) ~/ 12;
+      month = realMonth;
+    }
+
+    // First compute the seconds in UTC, independent of the [isUtc] flag. If
+    // necessary we will add the time-zone offset later on.
+    int days = day - 1;
+    days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month];
+    days += _dayFromYear(year);
+    int microsecondsSinceEpoch = days * Duration.microsecondsPerDay +
+        hour * Duration.microsecondsPerHour +
+        minute * Duration.microsecondsPerMinute +
+        second * Duration.microsecondsPerSecond +
+        millisecond * Duration.microsecondsPerMillisecond +
+        microsecond;
+
+    if (!isUtc) {
+      // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
+      // the valid range we do a preliminary test that weeds out values that can
+      // not become valid even with timezone adjustments.
+      // The timezone adjustment is always less than a day, so adding a security
+      // margin of one day should be enough.
+      if (microsecondsSinceEpoch.abs() >
+          _maxMillisecondsSinceEpoch * Duration.microsecondsPerMillisecond +
+              Duration.microsecondsPerDay) {
+        return null;
+      }
+
+      microsecondsSinceEpoch -= _toLocalTimeOffset(microsecondsSinceEpoch);
+    }
+    if (microsecondsSinceEpoch.abs() >
+        _maxMillisecondsSinceEpoch * Duration.microsecondsPerMillisecond) {
+      return null;
+    }
+    return microsecondsSinceEpoch;
+  }
+
+  static int _weekDay(y) {
+    // 1/1/1970 was a Thursday.
+    return (_dayFromYear(y) + 4) % 7;
+  }
+
+  /**
+   * Returns a year in the range 2008-2035 matching
+   * * leap year, and
+   * * week day of first day.
+   *
+   * Leap seconds are ignored.
+   * Adapted from V8's date implementation. See ECMA 262 - 15.9.1.9.
+   */
+  static int _equivalentYear(int year) {
+    // Returns year y so that _weekDay(y) == _weekDay(year).
+    // _weekDay returns the week day (in range 0 - 6).
+    // 1/1/1956 was a Sunday (i.e. weekday 0). 1956 was a leap-year.
+    // 1/1/1967 was a Sunday (i.e. weekday 0).
+    // Without leap years a subsequent year has a week day + 1 (for example
+    // 1/1/1968 was a Monday). With leap-years it jumps over one week day
+    // (e.g. 1/1/1957 was a Tuesday).
+    // After 12 years the weekdays have advanced by 12 days + 3 leap days =
+    // 15 days. 15 % 7 = 1. So after 12 years the week day has always
+    // (now independently of leap-years) advanced by one.
+    // weekDay * 12 gives thus a year starting with the wanted weekDay.
+    int recentYear = (_isLeapYear(year) ? 1956 : 1967) + (_weekDay(year) * 12);
+    // Close to the year 2008 the calendar cycles every 4 * 7 years (4 for the
+    // leap years, 7 for the weekdays).
+    // Find the year in the range 2008..2037 that is equivalent mod 28.
+    return 2008 + (recentYear - 2008) % 28;
+  }
+
+  /**
+   * Returns the UTC year for the corresponding [secondsSinceEpoch].
+   * It is relatively fast for values in the range 0 to year 2098.
+   *
+   * Code is adapted from V8.
+   */
+  static int _yearsFromSecondsSinceEpoch(int secondsSinceEpoch) {
+    const int DAYS_IN_4_YEARS = 4 * 365 + 1;
+    const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
+    const int DAYS_YEAR_2098 = DAYS_IN_100_YEARS + 6 * DAYS_IN_4_YEARS;
+
+    int days = secondsSinceEpoch ~/ Duration.secondsPerDay;
+    if (days > 0 && days < DAYS_YEAR_2098) {
+      // According to V8 this fast case works for dates from 1970 to 2099.
+      return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
+    }
+    int micros = secondsSinceEpoch * Duration.microsecondsPerSecond;
+    return _computeUpperPart(micros)[_YEAR_INDEX];
+  }
+
+  /**
+   * Returns a date in seconds that is equivalent to the given
+   * date in microseconds [microsecondsSinceEpoch]. An equivalent
+   * date has the same fields (`month`, `day`, etc.) as the given
+   * date, but the `year` is in the range [1901..2038].
+   *
+   * * The time since the beginning of the year is the same.
+   * * If the given date is in a leap year then the returned
+   *   seconds are in a leap year, too.
+   * * The week day of given date is the same as the one for the
+   *   returned date.
+   */
+  static int _equivalentSeconds(int microsecondsSinceEpoch) {
+    const int CUT_OFF_SECONDS = 0x7FFFFFFF;
+
+    int secondsSinceEpoch = _flooredDivision(
+        microsecondsSinceEpoch, Duration.microsecondsPerSecond);
+
+    if (secondsSinceEpoch.abs() > CUT_OFF_SECONDS) {
+      int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
+      int days = _dayFromYear(year);
+      int equivalentYear = _equivalentYear(year);
+      int equivalentDays = _dayFromYear(equivalentYear);
+      int diffDays = equivalentDays - days;
+      secondsSinceEpoch += diffDays * Duration.secondsPerDay;
+    }
+    return secondsSinceEpoch;
+  }
+
+  static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
+    int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
+    return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
+  }
+
+  static String _timeZoneName(int microsecondsSinceEpoch) {
+    int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
+    return _timeZoneNameForClampedSeconds(equivalentSeconds);
+  }
+
+  /// Finds the local time corresponding to a UTC date and time.
+  ///
+  /// The [microsecondsSinceEpoch] represents a particular
+  /// calendar date and clock time in UTC.
+  /// This methods returns a (usually different) point in time
+  /// where the local time had the same calendar date and clock
+  /// time (if such a time exists, otherwise it finds the "best"
+  /// substitute).
+  ///
+  /// A valid result is a point in time `microsecondsSinceEpoch - offset`
+  /// where the local time zone offset is `+offset`.
+  ///
+  /// In some cases there are two valid results, due to a time zone
+  /// change setting the clock back (for example exiting from daylight
+  /// saving time). In that case, we return the *earliest* valid result.
+  ///
+  /// In some cases there are no valid results, due to a time zone
+  /// change setting the clock forward (for example entering daylight
+  /// saving time). In that case, we return the time which would have
+  /// been correct in the earlier time zone (so asking for 2:30 AM
+  /// when clocks move directly from 2:00 to 3:00 will give the
+  /// time that *would have been* 2:30 in the earlier time zone,
+  /// which is now 3:30 in the local time zone).
+  ///
+  /// Returns the point in time as a number of microseconds since epoch.
+  static int _toLocalTimeOffset(int microsecondsSinceEpoch) {
+    // Argument is the UTC time corresponding to the desired
+    // calendar date/wall time.
+    // We now need to find an UTC time where the difference
+    // from `microsecondsSinceEpoch` is the same as the
+    // local time offset at that time. That is, we want to
+    // find `adjustment` in microseconds such that:
+    //
+    //  _timeZoneOffsetInSeconds(microsecondsSinceEpoch - offset)
+    //      * Duration.microsecondsPerSecond == offset
+    //
+    // Such an offset might not exist, if that wall time
+    // is skipped when a time zone change moves the clock forwards.
+    // In that case we pick a time after the switch which would be
+    // correct in the previous time zone.
+    // Also, there might be more than one solution if a time zone
+    // change moves the clock backwards and the same wall clock
+    // time occurs twice in the same day.
+    // In that case we pick the one in the time zone prior to
+    // the switch.
+
+    // Start with the time zone at the current microseconds since
+    // epoch. It's within one day of the real time we're looking for.
+
+    int offset = _timeZoneOffsetInSeconds(microsecondsSinceEpoch) *
+        Duration.microsecondsPerSecond;
+
+    // If offset is 0 (we're right around the UTC+0, and)
+    // we have found one solution.
+    if (offset != 0) {
+      // If not, try to find an actual solution in the time zone
+      // we just discovered.
+      int offset2 = _timeZoneOffsetInSeconds(microsecondsSinceEpoch - offset) *
+          Duration.microsecondsPerSecond;
+      if (offset2 != offset) {
+        // Also not a solution. We have found a second time zone
+        // within the same day. We assume that's all there are.
+        // Try again with the new time zone.
+        int offset3 =
+            _timeZoneOffsetInSeconds(microsecondsSinceEpoch - offset2) *
+                Duration.microsecondsPerSecond;
+        // Either offset3 is a solution (equal to offset2),
+        // or we have found two different time zones and no solution.
+        // In the latter case we choose the lower offset (latter time).
+        return (offset2 <= offset3 ? offset2 : offset3);
+      }
+      // We have found one solution and one time zone.
+      offset = offset2;
+    }
+    // Try to see if there is an earlier time zone which also
+    // has a solution.
+    // Pretends time zone changes are always at most two hours.
+    // (Double daylight saving happened, fx, in part of Canada in 1988).
+    int offset4 = _timeZoneOffsetInSeconds(microsecondsSinceEpoch -
+            offset -
+            2 * Duration.microsecondsPerHour) *
+        Duration.microsecondsPerSecond;
+    if (offset4 > offset) {
+      // The time zone at the earlier time had a greater
+      // offset, so it's possible that the desired wall clock
+      // occurs in that time zone too.
+      if (offset4 == offset + 2 * Duration.microsecondsPerHour) {
+        // A second and earlier solution, so use that.
+        return offset4;
+      }
+      // The time zone differs one hour earlier, but not by one
+      // hour, so check again in that time zone.
+      int offset5 = _timeZoneOffsetInSeconds(microsecondsSinceEpoch - offset4) *
+          Duration.microsecondsPerSecond;
+      if (offset5 == offset4) {
+        // Found a second solution earlier than the first solution, so use that.
+        return offset4;
+      }
+    }
+    // Did not find a solution in the earlier time
+    // zone, so just use the original result.
+    return offset;
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/developer.dart b/sdk/lib/_internal/wasm/lib/developer.dart
new file mode 100644
index 0000000..ba930b3
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/developer.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is a stub implementation of `dart:developer`.
+
+import "dart:_internal" show patch;
+
+import "dart:async" show Zone;
+
+// Stubs for `developer.dart`.
+
+@patch
+bool debugger({bool when: true, String? message}) => when;
+
+@patch
+Object? inspect(Object? object) => object;
+
+@patch
+void log(String message,
+    {DateTime? time,
+    int? sequenceNumber,
+    int level: 0,
+    String name: '',
+    Zone? zone,
+    Object? error,
+    StackTrace? stackTrace}) {}
+
+@patch
+void _postEvent(String eventKind, String eventData) {}
+
+@patch
+ServiceExtensionHandler? _lookupExtension(String method) => null;
+
+@patch
+_registerExtension(String method, ServiceExtensionHandler handler) {}
+
+// Stubs for `timeline.dart`.
+
+@patch
+bool _isDartStreamEnabled() => false;
+
+@patch
+int _getTraceClock() => _traceClock++;
+
+int _traceClock = 0;
+
+@patch
+int _getNextAsyncId() => 0;
+
+@patch
+void _reportTaskEvent(int taskId, String phase, String category, String name,
+    String argumentsAsJson) {}
+
+@patch
+void _reportFlowEvent(
+    String category, String name, int type, int id, String argumentsAsJson) {}
+
+@patch
+void _reportInstantEvent(
+    String category, String name, String argumentsAsJson) {}
diff --git a/sdk/lib/_internal/wasm/lib/double.dart b/sdk/lib/_internal/wasm/lib/double.dart
new file mode 100644
index 0000000..ea77a86
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/double.dart
@@ -0,0 +1,290 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+@pragma("wasm:entry-point")
+class _BoxedDouble implements double {
+  // A boxed double contains an unboxed double.
+  @pragma("wasm:entry-point")
+  double value = 0.0;
+
+  static const int _signMask = 0x8000000000000000;
+  static const int _exponentMask = 0x7FF0000000000000;
+  static const int _mantissaMask = 0x000FFFFFFFFFFFFF;
+
+  int get hashCode {
+    int bits = doubleToIntBits(this);
+    if (bits == _signMask) bits = 0; // 0.0 == -0.0
+    return mix64(bits);
+  }
+
+  int get _identityHashCode => hashCode;
+
+  double operator +(num other) => this + other.toDouble(); // Intrinsic +
+  double operator -(num other) => this - other.toDouble(); // Intrinsic -
+  double operator *(num other) => this * other.toDouble(); // Intrinsic *
+  double operator /(num other) => this / other.toDouble(); // Intrinsic /
+
+  int operator ~/(num other) {
+    return _truncDiv(this, other.toDouble());
+  }
+
+  static int _truncDiv(double a, double b) {
+    return (a / b).toInt();
+  }
+
+  double operator %(num other) {
+    return _modulo(this, other.toDouble());
+  }
+
+  static double _modulo(double a, double b) {
+    double rem = a - (a / b).truncateToDouble() * b;
+    if (rem == 0.0) return 0.0;
+    if (rem < 0.0) {
+      if (b < 0.0) {
+        return rem - b;
+      } else {
+        return rem + b;
+      }
+    }
+    return rem;
+  }
+
+  double remainder(num other) {
+    return _remainder(this, other.toDouble());
+  }
+
+  static double _remainder(double a, double b) {
+    return a - (a / b).truncateToDouble() * b;
+  }
+
+  external double operator -();
+
+  bool operator ==(Object other) {
+    return other is double
+        ? this == other // Intrinsic ==
+        : other is int
+            ? this == other.toDouble() // Intrinsic ==
+            : false;
+  }
+
+  bool operator <(num other) => this < other.toDouble(); // Intrinsic <
+  bool operator >(num other) => this > other.toDouble(); // Intrinsic >
+  bool operator >=(num other) => this >= other.toDouble(); // Intrinsic >=
+  bool operator <=(num other) => this <= other.toDouble(); // Intrinsic <=
+
+  bool get isNegative {
+    int bits = doubleToIntBits(this);
+    return (bits & _signMask) != 0;
+  }
+
+  bool get isInfinite {
+    int bits = doubleToIntBits(this);
+    return (bits & _exponentMask) == _exponentMask &&
+        (bits & _mantissaMask) == 0;
+  }
+
+  bool get isNaN {
+    int bits = doubleToIntBits(this);
+    return (bits & _exponentMask) == _exponentMask &&
+        (bits & _mantissaMask) != 0;
+  }
+
+  bool get isFinite {
+    int bits = doubleToIntBits(this);
+    return (bits & _exponentMask) != _exponentMask;
+  }
+
+  double abs() {
+    // Handle negative 0.0.
+    if (this == 0.0) return 0.0;
+    return this < 0.0 ? -this : this;
+  }
+
+  double get sign {
+    if (this > 0.0) return 1.0;
+    if (this < 0.0) return -1.0;
+    return this; // +/-0.0 or NaN.
+  }
+
+  int round() => roundToDouble().toInt();
+  int floor() => floorToDouble().toInt();
+  int ceil() => ceilToDouble().toInt();
+  int truncate() => truncateToDouble().toInt();
+
+  external double roundToDouble();
+  external double floorToDouble();
+  external double ceilToDouble();
+  external double truncateToDouble();
+
+  num clamp(num lowerLimit, num upperLimit) {
+    if (lowerLimit.compareTo(upperLimit) > 0) {
+      throw new ArgumentError(lowerLimit);
+    }
+    if (lowerLimit.isNaN) return lowerLimit;
+    if (this.compareTo(lowerLimit) < 0) return lowerLimit;
+    if (this.compareTo(upperLimit) > 0) return upperLimit;
+    return this;
+  }
+
+  external int toInt();
+
+  double toDouble() {
+    return this;
+  }
+
+  static const int CACHE_SIZE_LOG2 = 3;
+  static const int CACHE_LENGTH = 1 << (CACHE_SIZE_LOG2 + 1);
+  static const int CACHE_MASK = CACHE_LENGTH - 1;
+  // Each key (double) followed by its toString result.
+  static final List _cache = new List.filled(CACHE_LENGTH, null);
+  static int _cacheEvictIndex = 0;
+
+  external String _toString();
+
+  String toString() {
+    // TODO(koda): Consider starting at most recently inserted.
+    for (int i = 0; i < CACHE_LENGTH; i += 2) {
+      // Need 'identical' to handle negative zero, etc.
+      if (identical(_cache[i], this)) {
+        return _cache[i + 1];
+      }
+    }
+    // TODO(koda): Consider optimizing all small integral values.
+    if (identical(0.0, this)) {
+      return "0.0";
+    }
+    String result = _toString();
+    // Replace the least recently inserted entry.
+    _cache[_cacheEvictIndex] = this;
+    _cache[_cacheEvictIndex + 1] = result;
+    _cacheEvictIndex = (_cacheEvictIndex + 2) & CACHE_MASK;
+    return result;
+  }
+
+  String toStringAsFixed(int fractionDigits) {
+    // See ECMAScript-262, 15.7.4.5 for details.
+
+    // Step 2.
+    if (fractionDigits < 0 || fractionDigits > 20) {
+      throw new RangeError.range(fractionDigits, 0, 20, "fractionDigits");
+    }
+
+    // Step 3.
+    double x = this;
+
+    // Step 4.
+    if (isNaN) return "NaN";
+
+    // Step 5 and 6 skipped. Will be dealt with by native function.
+
+    // Step 7.
+    if (x >= 1e21 || x <= -1e21) {
+      return x.toString();
+    }
+
+    return _toStringAsFixed(fractionDigits);
+  }
+
+  external String _toStringAsFixed(int fractionDigits);
+
+  String toStringAsExponential([int? fractionDigits]) {
+    // See ECMAScript-262, 15.7.4.6 for details.
+
+    // The EcmaScript specification checks for NaN and Infinity before looking
+    // at the fractionDigits. In Dart we are consistent with toStringAsFixed and
+    // look at the fractionDigits first.
+
+    // Step 7.
+    if (fractionDigits != null) {
+      if (fractionDigits < 0 || fractionDigits > 20) {
+        throw new RangeError.range(fractionDigits, 0, 20, "fractionDigits");
+      }
+    }
+
+    if (isNaN) return "NaN";
+    if (this == double.infinity) return "Infinity";
+    if (this == -double.infinity) return "-Infinity";
+
+    // The dart function prints the shortest representation when fractionDigits
+    // equals null. The native function wants -1 instead.
+    fractionDigits = (fractionDigits == null) ? -1 : fractionDigits;
+
+    return _toStringAsExponential(fractionDigits);
+  }
+
+  external String _toStringAsExponential(int fractionDigits);
+
+  String toStringAsPrecision(int precision) {
+    // See ECMAScript-262, 15.7.4.7 for details.
+
+    // The EcmaScript specification checks for NaN and Infinity before looking
+    // at the fractionDigits. In Dart we are consistent with toStringAsFixed and
+    // look at the fractionDigits first.
+
+    // Step 8.
+    if (precision < 1 || precision > 21) {
+      throw new RangeError.range(precision, 1, 21, "precision");
+    }
+
+    if (isNaN) return "NaN";
+    if (this == double.infinity) return "Infinity";
+    if (this == -double.infinity) return "-Infinity";
+
+    return _toStringAsPrecision(precision);
+  }
+
+  external String _toStringAsPrecision(int fractionDigits);
+
+  // Order is: NaN > Infinity > ... > 0.0 > -0.0 > ... > -Infinity.
+  int compareTo(num other) {
+    const int EQUAL = 0, LESS = -1, GREATER = 1;
+    if (this < other) {
+      return LESS;
+    } else if (this > other) {
+      return GREATER;
+    } else if (this == other) {
+      if (this == 0.0) {
+        bool thisIsNegative = isNegative;
+        bool otherIsNegative = other.isNegative;
+        if (thisIsNegative == otherIsNegative) {
+          return EQUAL;
+        }
+        return thisIsNegative ? LESS : GREATER;
+      } else if (other is int) {
+        // Compare as integers as it is more precise if the integer value is
+        // outside of MIN_EXACT_INT_TO_DOUBLE..MAX_EXACT_INT_TO_DOUBLE range.
+        const int MAX_EXACT_INT_TO_DOUBLE = 9007199254740992; // 2^53.
+        const int MIN_EXACT_INT_TO_DOUBLE = -MAX_EXACT_INT_TO_DOUBLE;
+        if ((MIN_EXACT_INT_TO_DOUBLE <= other) &&
+            (other <= MAX_EXACT_INT_TO_DOUBLE)) {
+          return EQUAL;
+        }
+        const bool limitIntsTo64Bits = ((1 << 64) == 0);
+        if (limitIntsTo64Bits) {
+          // With integers limited to 64 bits, double.toInt() clamps
+          // double value to fit into the MIN_INT64..MAX_INT64 range.
+          // MAX_INT64 is not precisely representable as double, so
+          // integers near MAX_INT64 compare as equal to (MAX_INT64 + 1) when
+          // represented as doubles.
+          // There is no similar problem with MIN_INT64 as it is precisely
+          // representable as double.
+          const double maxInt64Plus1AsDouble = 9223372036854775808.0;
+          if (this >= maxInt64Plus1AsDouble) {
+            return GREATER;
+          }
+        }
+        return toInt().compareTo(other);
+      } else {
+        return EQUAL;
+      }
+    } else if (isNaN) {
+      return other.isNaN ? EQUAL : GREATER;
+    } else {
+      // Other is NaN.
+      return LESS;
+    }
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/expando_patch.dart b/sdk/lib/_internal/wasm/lib/expando_patch.dart
new file mode 100644
index 0000000..2be5189
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/expando_patch.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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 "dart:_internal" show patch;
+
+// Stub Expando implementation to make the Expando class compile.
+
+@patch
+class Expando<T> {
+  @patch
+  Expando([String? name]) : name = name;
+}
diff --git a/sdk/lib/_internal/wasm/lib/function.dart b/sdk/lib/_internal/wasm/lib/function.dart
new file mode 100644
index 0000000..b698573
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/function.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, 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.
+
+/// Base class for closure objects.
+@pragma("wasm:entry-point")
+class _Function {
+  @pragma("wasm:entry-point")
+  WasmDataRef context;
+
+  _Function._(this.context);
+}
diff --git a/sdk/lib/_internal/wasm/lib/growable_list.dart b/sdk/lib/_internal/wasm/lib/growable_list.dart
new file mode 100644
index 0000000..7b4912b
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/growable_list.dart
@@ -0,0 +1,305 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+@pragma("wasm:entry-point")
+class _GrowableList<E> extends _ModifiableList<E> {
+  void insert(int index, E element) {
+    if ((index < 0) || (index > length)) {
+      throw new RangeError.range(index, 0, length);
+    }
+    int oldLength = this.length;
+    add(element);
+    if (index == oldLength) {
+      return;
+    }
+    Lists.copy(this, index, this, index + 1, oldLength - index);
+    this[index] = element;
+  }
+
+  E removeAt(int index) {
+    var result = this[index];
+    int newLength = this.length - 1;
+    if (index < newLength) {
+      Lists.copy(this, index + 1, this, index, newLength - index);
+    }
+    this.length = newLength;
+    return result;
+  }
+
+  bool remove(Object? element) {
+    for (int i = 0; i < this.length; i++) {
+      if (this[i] == element) {
+        removeAt(i);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void insertAll(int index, Iterable<E> iterable) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (iterable is! _ListBase) {
+      // Read out all elements before making room to ensure consistency of the
+      // modified list in case the iterator throws.
+      iterable = _List.of(iterable);
+    }
+    int insertionLength = iterable.length;
+    int capacity = _capacity;
+    int newLength = length + insertionLength;
+    if (newLength > capacity) {
+      do {
+        capacity = _nextCapacity(capacity);
+      } while (newLength > capacity);
+      _grow(capacity);
+    }
+    _setLength(newLength);
+    setRange(index + insertionLength, this.length, this, index);
+    setAll(index, iterable);
+  }
+
+  void removeRange(int start, int end) {
+    RangeError.checkValidRange(start, end, this.length);
+    Lists.copy(this, end, this, start, this.length - end);
+    this.length = this.length - (end - start);
+  }
+
+  _GrowableList._(int length, int capacity) : super(length, capacity);
+
+  factory _GrowableList(int length) {
+    return _GrowableList<E>._(length, length);
+  }
+
+  factory _GrowableList.withCapacity(int capacity) {
+    return _GrowableList<E>._(0, capacity);
+  }
+
+  // Specialization of List.empty constructor for growable == true.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  factory _GrowableList.empty() => _GrowableList(0);
+
+  // Specialization of List.filled constructor for growable == true.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  factory _GrowableList.filled(int length, E fill) {
+    final result = _GrowableList<E>(length);
+    if (fill != null) {
+      for (int i = 0; i < result.length; i++) {
+        result[i] = fill;
+      }
+    }
+    return result;
+  }
+
+  // Specialization of List.generate constructor for growable == true.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  factory _GrowableList.generate(int length, E generator(int index)) {
+    final result = _GrowableList<E>(length);
+    for (int i = 0; i < result.length; ++i) {
+      result[i] = generator(i);
+    }
+    return result;
+  }
+
+  // Specialization of List.of constructor for growable == true.
+  factory _GrowableList.of(Iterable<E> elements) {
+    if (elements is _ListBase) {
+      return _GrowableList._ofListBase(unsafeCast(elements));
+    }
+    if (elements is EfficientLengthIterable) {
+      return _GrowableList._ofEfficientLengthIterable(unsafeCast(elements));
+    }
+    return _GrowableList._ofOther(elements);
+  }
+
+  factory _GrowableList._ofListBase(_ListBase<E> elements) {
+    final int length = elements.length;
+    final list = _GrowableList<E>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _GrowableList._ofEfficientLengthIterable(
+      EfficientLengthIterable<E> elements) {
+    final int length = elements.length;
+    final list = _GrowableList<E>(length);
+    if (length > 0) {
+      int i = 0;
+      for (var element in elements) {
+        list[i++] = element;
+      }
+      if (i != length) throw ConcurrentModificationError(elements);
+    }
+    return list;
+  }
+
+  factory _GrowableList._ofOther(Iterable<E> elements) {
+    final list = _GrowableList<E>(0);
+    for (var elements in elements) {
+      list.add(elements);
+    }
+    return list;
+  }
+
+  _GrowableList._withData(WasmObjectArray<Object?> data)
+      : super._withData(data.length, data);
+
+  int get _capacity => _data.length;
+
+  void set length(int new_length) {
+    if (new_length > length) {
+      // Verify that element type is nullable.
+      null as E;
+      if (new_length > _capacity) {
+        _grow(new_length);
+      }
+      _setLength(new_length);
+      return;
+    }
+    final int new_capacity = new_length;
+    // We are shrinking. Pick the method which has fewer writes.
+    // In the shrink-to-fit path, we write |new_capacity + new_length| words
+    // (null init + copy).
+    // In the non-shrink-to-fit path, we write |length - new_length| words
+    // (null overwrite).
+    final bool shouldShrinkToFit =
+        (new_capacity + new_length) < (length - new_length);
+    if (shouldShrinkToFit) {
+      _shrink(new_capacity, new_length);
+    } else {
+      for (int i = new_length; i < length; i++) {
+        _data.write(i, null);
+      }
+    }
+    _setLength(new_length);
+  }
+
+  void _setLength(int new_length) {
+    _length = new_length;
+  }
+
+  void add(E value) {
+    var len = length;
+    if (len == _capacity) {
+      _growToNextCapacity();
+    }
+    _setLength(len + 1);
+    this[len] = value;
+  }
+
+  void addAll(Iterable<E> iterable) {
+    var len = length;
+    if (iterable is EfficientLengthIterable) {
+      if (identical(iterable, this)) {
+        throw new ConcurrentModificationError(this);
+      }
+      var cap = _capacity;
+      // Pregrow if we know iterable.length.
+      var iterLen = iterable.length;
+      if (iterLen == 0) {
+        return;
+      }
+      var newLen = len + iterLen;
+      if (newLen > cap) {
+        do {
+          cap = _nextCapacity(cap);
+        } while (newLen > cap);
+        _grow(cap);
+      }
+    }
+    Iterator it = iterable.iterator;
+    if (!it.moveNext()) return;
+    do {
+      while (len < _capacity) {
+        int newLen = len + 1;
+        this._setLength(newLen);
+        this[len] = it.current;
+        if (!it.moveNext()) return;
+        if (this.length != newLen) throw new ConcurrentModificationError(this);
+        len = newLen;
+      }
+      _growToNextCapacity();
+    } while (true);
+  }
+
+  E removeLast() {
+    var len = length - 1;
+    var elem = this[len];
+    this.length = len;
+    return elem;
+  }
+
+  // Shared array used as backing for new empty growable lists.
+  static final WasmObjectArray<Object?> _emptyData =
+      WasmObjectArray<Object?>(0);
+
+  static WasmObjectArray<Object?> _allocateData(int capacity) {
+    if (capacity == 0) {
+      // Use shared empty list as backing.
+      return _emptyData;
+    }
+    return new WasmObjectArray<Object?>(capacity);
+  }
+
+  // Grow from 0 to 3, and then double + 1.
+  int _nextCapacity(int old_capacity) => (old_capacity * 2) | 3;
+
+  void _grow(int new_capacity) {
+    var newData = WasmObjectArray<Object?>(new_capacity);
+    for (int i = 0; i < length; i++) {
+      newData.write(i, this[i]);
+    }
+    _data = newData;
+  }
+
+  void _growToNextCapacity() {
+    _grow(_nextCapacity(_capacity));
+  }
+
+  void _shrink(int new_capacity, int new_length) {
+    var newData = _allocateData(new_capacity);
+    for (int i = 0; i < new_length; i++) {
+      newData.write(i, this[i]);
+    }
+    _data = newData;
+  }
+
+  Iterator<E> get iterator {
+    return new _GrowableListIterator<E>(this);
+  }
+}
+
+// Iterator for growable lists.
+class _GrowableListIterator<E> implements Iterator<E> {
+  final _GrowableList<E> _list;
+  final int _length; // Cache list length for modification check.
+  int _index;
+  E? _current;
+
+  _GrowableListIterator(_GrowableList<E> list)
+      : _list = list,
+        _length = list.length,
+        _index = 0 {
+    assert(list is _List<E> || list is _ImmutableList<E>);
+  }
+
+  E get current => _current as E;
+
+  bool moveNext() {
+    if (_list.length != _length) {
+      throw ConcurrentModificationError(_list);
+    }
+    if (_index >= _length) {
+      _current = null;
+      return false;
+    }
+    _current = unsafeCast(_list._data.read(_index));
+    _index++;
+    return true;
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/hash_factories.dart b/sdk/lib/_internal/wasm/lib/hash_factories.dart
new file mode 100644
index 0000000..4217e38
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/hash_factories.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, 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.
+
+@patch
+class LinkedHashMap<K, V> {
+  @patch
+  factory LinkedHashMap(
+      {bool equals(K key1, K key2)?,
+      int hashCode(K key)?,
+      bool isValidKey(potentialKey)?}) {
+    if (isValidKey == null) {
+      if (identical(identityHashCode, hashCode) &&
+          identical(identical, equals)) {
+        return new _CompactLinkedIdentityHashMap<K, V>();
+      }
+    }
+    hashCode ??= _defaultHashCode;
+    equals ??= _defaultEquals;
+    return new _CompactLinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
+  }
+
+  @pragma("wasm:entry-point")
+  factory LinkedHashMap._default() =>
+      _CompactLinkedCustomHashMap<K, V>(_defaultEquals, _defaultHashCode, null);
+
+  @patch
+  factory LinkedHashMap.identity() => new _CompactLinkedIdentityHashMap<K, V>();
+}
+
+@patch
+class LinkedHashSet<E> {
+  @patch
+  factory LinkedHashSet(
+      {bool equals(E e1, E e2)?,
+      int hashCode(E e)?,
+      bool isValidKey(potentialKey)?}) {
+    if (isValidKey == null) {
+      if (identical(identityHashCode, hashCode) &&
+          identical(identical, equals)) {
+        return new _CompactLinkedIdentityHashSet<E>();
+      }
+    }
+    hashCode ??= _defaultHashCode;
+    equals ??= _defaultEquals;
+    return new _CompactLinkedCustomHashSet<E>(equals, hashCode, isValidKey);
+  }
+
+  @patch
+  factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet<E>();
+}
diff --git a/sdk/lib/_internal/wasm/lib/identical_patch.dart b/sdk/lib/_internal/wasm/lib/identical_patch.dart
new file mode 100644
index 0000000..614bef6
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/identical_patch.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+@patch
+external bool identical(Object? a, Object? b);
+
+@patch
+int identityHashCode(Object? object) =>
+    object == null ? Null._HASH_CODE : object._identityHashCode;
diff --git a/sdk/lib/_internal/wasm/lib/immutable_map.dart b/sdk/lib/_internal/wasm/lib/immutable_map.dart
new file mode 100644
index 0000000..74127f4
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/immutable_map.dart
@@ -0,0 +1,221 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+/// Immutable map class for compiler generated map literals.
+// TODO(lrn): Extend MapBase with UnmodifiableMapMixin when mixins
+// support forwarding const constructors.
+@pragma("wasm:entry-point")
+class _ImmutableMap<K, V> implements Map<K, V> {
+  final _ImmutableList _kvPairs;
+
+  @pragma("wasm:entry-point")
+  const _ImmutableMap._create(_ImmutableList keyValuePairs)
+      : _kvPairs = keyValuePairs;
+
+  Map<K2, V2> cast<K2, V2>() => Map.castFrom<K, V, K2, V2>(this);
+
+  V? operator [](Object? key) {
+    // To preserve the key-value order of the map literal, the keys are
+    // not sorted. Need to do linear search or implement an additional
+    // lookup table.
+    for (int i = 0; i < _kvPairs.length - 1; i += 2) {
+      if (key == _kvPairs[i]) {
+        return _kvPairs[i + 1];
+      }
+    }
+    return null;
+  }
+
+  bool get isEmpty {
+    return _kvPairs.length == 0;
+  }
+
+  bool get isNotEmpty => !isEmpty;
+
+  int get length {
+    return _kvPairs.length ~/ 2;
+  }
+
+  void forEach(void f(K key, V value)) {
+    for (int i = 0; i < _kvPairs.length; i += 2) {
+      f(_kvPairs[i], _kvPairs[i + 1]);
+    }
+  }
+
+  Iterable<K> get keys {
+    return new _ImmutableMapKeyIterable<K>(this);
+  }
+
+  Iterable<V> get values {
+    return new _ImmutableMapValueIterable<V>(this);
+  }
+
+  bool containsKey(Object? key) {
+    for (int i = 0; i < _kvPairs.length; i += 2) {
+      if (key == _kvPairs[i]) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool containsValue(Object? value) {
+    for (int i = 1; i < _kvPairs.length; i += 2) {
+      if (value == _kvPairs[i]) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void operator []=(K key, V value) {
+    throw new UnsupportedError("Cannot set value in unmodifiable Map");
+  }
+
+  void addAll(Map<K, V> other) {
+    throw new UnsupportedError("Cannot set value in unmodifiable Map");
+  }
+
+  V putIfAbsent(K key, V ifAbsent()) {
+    throw new UnsupportedError("Cannot set value in unmodifiable Map");
+  }
+
+  void clear() {
+    throw new UnsupportedError("Cannot clear unmodifiable Map");
+  }
+
+  V? remove(Object? key) {
+    throw new UnsupportedError("Cannot remove from unmodifiable Map");
+  }
+
+  Iterable<MapEntry<K, V>> get entries =>
+      new _ImmutableMapEntryIterable<K, V>(this);
+
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> f(K key, V value)) {
+    var result = <K2, V2>{};
+    for (int i = 0; i < _kvPairs.length; i += 2) {
+      var entry = f(_kvPairs[i], _kvPairs[i + 1]);
+      result[entry.key] = entry.value;
+    }
+    return result;
+  }
+
+  void addEntries(Iterable<MapEntry<K, V>> newEntries) {
+    throw new UnsupportedError("Cannot modify an unmodifiable Map");
+  }
+
+  V update(K key, V update(V value), {V ifAbsent()?}) {
+    throw new UnsupportedError("Cannot modify an unmodifiable Map");
+  }
+
+  void updateAll(V update(K key, V value)) {
+    throw new UnsupportedError("Cannot modify an unmodifiable Map");
+  }
+
+  void removeWhere(bool predicate(K key, V value)) {
+    throw new UnsupportedError("Cannot modify an unmodifiable Map");
+  }
+
+  String toString() => MapBase.mapToString(this);
+}
+
+class _ImmutableMapKeyIterable<E> extends EfficientLengthIterable<E> {
+  final _ImmutableMap _map;
+  _ImmutableMapKeyIterable(this._map);
+
+  Iterator<E> get iterator {
+    return new _ImmutableMapKeyIterator<E>(_map);
+  }
+
+  int get length => _map.length;
+}
+
+class _ImmutableMapValueIterable<E> extends EfficientLengthIterable<E> {
+  final _ImmutableMap _map;
+  _ImmutableMapValueIterable(this._map);
+
+  Iterator<E> get iterator {
+    return new _ImmutableMapValueIterator<E>(_map);
+  }
+
+  int get length => _map.length;
+}
+
+class _ImmutableMapEntryIterable<K, V>
+    extends EfficientLengthIterable<MapEntry<K, V>> {
+  final _ImmutableMap _map;
+  _ImmutableMapEntryIterable(this._map);
+
+  Iterator<MapEntry<K, V>> get iterator {
+    return new _ImmutableMapEntryIterator<K, V>(_map);
+  }
+
+  int get length => _map.length;
+}
+
+class _ImmutableMapKeyIterator<E> implements Iterator<E> {
+  _ImmutableMap _map;
+  int _nextIndex = 0;
+  E? _current;
+
+  _ImmutableMapKeyIterator(this._map);
+
+  bool moveNext() {
+    int newIndex = _nextIndex;
+    if (newIndex < _map.length) {
+      _nextIndex = newIndex + 1;
+      _current = _map._kvPairs[newIndex * 2];
+      return true;
+    }
+    _current = null;
+    return false;
+  }
+
+  E get current => _current as E;
+}
+
+class _ImmutableMapValueIterator<E> implements Iterator<E> {
+  _ImmutableMap _map;
+  int _nextIndex = 0;
+  E? _current;
+
+  _ImmutableMapValueIterator(this._map);
+
+  bool moveNext() {
+    int newIndex = _nextIndex;
+    if (newIndex < _map.length) {
+      _nextIndex = newIndex + 1;
+      _current = _map._kvPairs[newIndex * 2 + 1];
+      return true;
+    }
+    _current = null;
+    return false;
+  }
+
+  E get current => _current as E;
+}
+
+class _ImmutableMapEntryIterator<K, V> implements Iterator<MapEntry<K, V>> {
+  _ImmutableMap _map;
+  int _nextIndex = 0;
+  MapEntry<K, V>? _current;
+
+  _ImmutableMapEntryIterator(this._map);
+
+  bool moveNext() {
+    int newIndex = _nextIndex;
+    if (newIndex < _map.length) {
+      _nextIndex = newIndex + 1;
+      _current = new MapEntry<K, V>(
+          _map._kvPairs[newIndex * 2], _map._kvPairs[newIndex * 2 + 1]);
+      return true;
+    }
+    _current = null;
+    return false;
+  }
+
+  MapEntry<K, V> get current => _current as MapEntry<K, V>;
+}
diff --git a/sdk/lib/_internal/wasm/lib/int.dart b/sdk/lib/_internal/wasm/lib/int.dart
new file mode 100644
index 0000000..e41f186
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/int.dart
@@ -0,0 +1,610 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+@pragma("wasm:entry-point")
+class _BoxedInt implements int {
+  // A boxed int contains an unboxed int.
+  @pragma("wasm:entry-point")
+  int value = 0;
+
+  external num operator +(num other);
+  external num operator -(num other);
+  external num operator *(num other);
+
+  double operator /(num other) {
+    return this.toDouble() / other.toDouble();
+  }
+
+  int operator ~/(num other) => other is int
+      ? this ~/ other
+      : _BoxedDouble._truncDiv(toDouble(), unsafeCast<double>(other));
+
+  num operator %(num other) => other is int
+      ? _modulo(this, other)
+      : _BoxedDouble._modulo(toDouble(), unsafeCast<double>(other));
+
+  static int _modulo(int a, int b) {
+    int rem = a - (a ~/ b) * b;
+    if (rem < 0) {
+      if (b < 0) {
+        return rem - b;
+      } else {
+        return rem + b;
+      }
+    }
+    return rem;
+  }
+
+  num remainder(num other) => other is int
+      ? this - (this ~/ other) * other
+      : _BoxedDouble._remainder(toDouble(), unsafeCast<double>(other));
+
+  external int operator -();
+
+  external int operator &(int other);
+  external int operator |(int other);
+  external int operator ^(int other);
+
+  external int operator >>(int other);
+  external int operator >>>(int other);
+  external int operator <<(int other);
+
+  external bool operator <(num other);
+  external bool operator >(num other);
+  external bool operator >=(num other);
+  external bool operator <=(num other);
+
+  bool operator ==(Object other) {
+    return other is int
+        ? this == other // Intrinsic ==
+        : other is double
+            ? this.toDouble() == other // Intrinsic ==
+            : false;
+  }
+
+  int abs() {
+    return this < 0 ? -this : this;
+  }
+
+  int get sign {
+    return (this > 0)
+        ? 1
+        : (this < 0)
+            ? -1
+            : 0;
+  }
+
+  bool get isEven => (this & 1) == 0;
+  bool get isOdd => (this & 1) != 0;
+  bool get isNaN => false;
+  bool get isNegative => this < 0;
+  bool get isInfinite => false;
+  bool get isFinite => true;
+
+  int toUnsigned(int width) {
+    return this & ((1 << width) - 1);
+  }
+
+  int toSigned(int width) {
+    // The value of binary number weights each bit by a power of two.  The
+    // twos-complement value weights the sign bit negatively.  We compute the
+    // value of the negative weighting by isolating the sign bit with the
+    // correct power of two weighting and subtracting it from the value of the
+    // lower bits.
+    int signMask = 1 << (width - 1);
+    return (this & (signMask - 1)) - (this & signMask);
+  }
+
+  int compareTo(num other) {
+    const int EQUAL = 0, LESS = -1, GREATER = 1;
+    if (other is double) {
+      const int MAX_EXACT_INT_TO_DOUBLE = 9007199254740992; // 2^53.
+      const int MIN_EXACT_INT_TO_DOUBLE = -MAX_EXACT_INT_TO_DOUBLE;
+      // With int limited to 64 bits, double.toInt() clamps
+      // double value to fit into the MIN_INT64..MAX_INT64 range.
+      // Check if the double value is outside of this range.
+      // This check handles +/-infinity as well.
+      const double minInt64AsDouble = -9223372036854775808.0;
+      // MAX_INT64 is not precisely representable in doubles, so
+      // check against (MAX_INT64 + 1).
+      const double maxInt64Plus1AsDouble = 9223372036854775808.0;
+      if (other < minInt64AsDouble) {
+        return GREATER;
+      } else if (other >= maxInt64Plus1AsDouble) {
+        return LESS;
+      }
+      if (other.isNaN) {
+        return LESS;
+      }
+      if (MIN_EXACT_INT_TO_DOUBLE <= this && this <= MAX_EXACT_INT_TO_DOUBLE) {
+        // Let the double implementation deal with -0.0.
+        return -(other.compareTo(this.toDouble()));
+      } else {
+        // If abs(other) > MAX_EXACT_INT_TO_DOUBLE, then other has an integer
+        // value (no bits below the decimal point).
+        other = other.toInt();
+      }
+    }
+    if (this < other) {
+      return LESS;
+    } else if (this > other) {
+      return GREATER;
+    } else {
+      return EQUAL;
+    }
+  }
+
+  int round() {
+    return this;
+  }
+
+  int floor() {
+    return this;
+  }
+
+  int ceil() {
+    return this;
+  }
+
+  int truncate() {
+    return this;
+  }
+
+  double roundToDouble() {
+    return this.toDouble();
+  }
+
+  double floorToDouble() {
+    return this.toDouble();
+  }
+
+  double ceilToDouble() {
+    return this.toDouble();
+  }
+
+  double truncateToDouble() {
+    return this.toDouble();
+  }
+
+  num clamp(num lowerLimit, num upperLimit) {
+    // Special case for integers.
+    if (lowerLimit is int && upperLimit is int && lowerLimit <= upperLimit) {
+      if (this < lowerLimit) return lowerLimit;
+      if (this > upperLimit) return upperLimit;
+      return this;
+    }
+    // Generic case involving doubles, and invalid integer ranges.
+    if (lowerLimit.compareTo(upperLimit) > 0) {
+      throw new ArgumentError(lowerLimit);
+    }
+    if (lowerLimit.isNaN) return lowerLimit;
+    // Note that we don't need to care for -0.0 for the lower limit.
+    if (this < lowerLimit) return lowerLimit;
+    if (this.compareTo(upperLimit) > 0) return upperLimit;
+    return this;
+  }
+
+  int toInt() {
+    return this;
+  }
+
+  external double toDouble();
+
+  String toStringAsFixed(int fractionDigits) {
+    return this.toDouble().toStringAsFixed(fractionDigits);
+  }
+
+  String toStringAsExponential([int? fractionDigits]) {
+    return this.toDouble().toStringAsExponential(fractionDigits);
+  }
+
+  String toStringAsPrecision(int precision) {
+    return this.toDouble().toStringAsPrecision(precision);
+  }
+
+  static const _digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+  String toRadixString(int radix) {
+    if (radix < 2 || 36 < radix) {
+      throw new RangeError.range(radix, 2, 36, "radix");
+    }
+    if (radix & (radix - 1) == 0) {
+      return _toPow2String(radix);
+    }
+    if (radix == 10) return this.toString();
+    final bool isNegative = this < 0;
+    int value = isNegative ? -this : this;
+    if (value < 0) {
+      // With int limited to 64 bits, the value
+      // MIN_INT64 = -0x8000000000000000 overflows at negation:
+      // -MIN_INT64 == MIN_INT64, so it requires special handling.
+      return _minInt64ToRadixString(radix);
+    }
+    var temp = <int>[];
+    do {
+      int digit = value % radix;
+      value ~/= radix;
+      temp.add(_digits.codeUnitAt(digit));
+    } while (value > 0);
+    if (isNegative) temp.add(0x2d); // '-'.
+
+    _OneByteString string = _OneByteString._allocate(temp.length);
+    for (int i = 0, j = temp.length; j > 0; i++) {
+      string._setAt(i, temp[--j]);
+    }
+    return string;
+  }
+
+  String _toPow2String(int radix) {
+    int value = this;
+    if (value == 0) return "0";
+    assert(radix & (radix - 1) == 0);
+    var negative = value < 0;
+    var bitsPerDigit = radix.bitLength - 1;
+    var length = 0;
+    if (negative) {
+      value = -value;
+      length = 1;
+      if (value < 0) {
+        // With int limited to 64 bits, the value
+        // MIN_INT64 = -0x8000000000000000 overflows at negation:
+        // -MIN_INT64 == MIN_INT64, so it requires special handling.
+        return _minInt64ToRadixString(radix);
+      }
+    }
+    // Integer division, rounding up, to find number of _digits.
+    length += (value.bitLength + bitsPerDigit - 1) ~/ bitsPerDigit;
+    _OneByteString string = _OneByteString._allocate(length);
+    string._setAt(0, 0x2d); // '-'. Is overwritten if not negative.
+    var mask = radix - 1;
+    do {
+      string._setAt(--length, _digits.codeUnitAt(value & mask));
+      value >>= bitsPerDigit;
+    } while (value > 0);
+    return string;
+  }
+
+  /// Converts negative value to radix string.
+  /// This method is only used to handle corner case of
+  /// MIN_INT64 = -0x8000000000000000.
+  String _minInt64ToRadixString(int radix) {
+    var temp = <int>[];
+    int value = this;
+    assert(value < 0);
+    do {
+      int digit = -unsafeCast<int>(value.remainder(radix));
+      value ~/= radix;
+      temp.add(_digits.codeUnitAt(digit));
+    } while (value != 0);
+    temp.add(0x2d); // '-'.
+
+    _OneByteString string = _OneByteString._allocate(temp.length);
+    for (int i = 0, j = temp.length; j > 0; i++) {
+      string._setAt(i, temp[--j]);
+    }
+    return string;
+  }
+
+  // Returns pow(this, e) % m.
+  int modPow(int e, int m) {
+    if (e < 0) throw new RangeError.range(e, 0, null, "exponent");
+    if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
+    if (e == 0) return 1;
+
+    // This is floor(sqrt(2^63)).
+    const int maxValueThatCanBeSquaredWithoutTruncation = 3037000499;
+    if (m > maxValueThatCanBeSquaredWithoutTruncation) {
+      // Use BigInt version to avoid truncation in multiplications below.
+      return BigInt.from(this).modPow(BigInt.from(e), BigInt.from(m)).toInt();
+    }
+
+    int b = this;
+    if (b < 0 || b > m) {
+      b %= m;
+    }
+    int r = 1;
+    while (e > 0) {
+      if (e.isOdd) {
+        r = (r * b) % m;
+      }
+      e >>= 1;
+      b = (b * b) % m;
+    }
+    return r;
+  }
+
+  // If inv is false, returns gcd(x, y).
+  // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+  // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+  static int _binaryGcd(int x, int y, bool inv) {
+    int s = 0;
+    if (!inv) {
+      while (x.isEven && y.isEven) {
+        x >>= 1;
+        y >>= 1;
+        s++;
+      }
+      if (y.isOdd) {
+        var t = x;
+        x = y;
+        y = t;
+      }
+    }
+    final bool ac = x.isEven;
+    int u = x;
+    int v = y;
+    int a = 1, b = 0, c = 0, d = 1;
+    do {
+      while (u.isEven) {
+        u >>= 1;
+        if (ac) {
+          if (!a.isEven || !b.isEven) {
+            a += y;
+            b -= x;
+          }
+          a >>= 1;
+        } else if (!b.isEven) {
+          b -= x;
+        }
+        b >>= 1;
+      }
+      while (v.isEven) {
+        v >>= 1;
+        if (ac) {
+          if (!c.isEven || !d.isEven) {
+            c += y;
+            d -= x;
+          }
+          c >>= 1;
+        } else if (!d.isEven) {
+          d -= x;
+        }
+        d >>= 1;
+      }
+      if (u >= v) {
+        u -= v;
+        if (ac) a -= c;
+        b -= d;
+      } else {
+        v -= u;
+        if (ac) c -= a;
+        d -= b;
+      }
+    } while (u != 0);
+    if (!inv) return v << s;
+    if (v != 1) {
+      throw new Exception("Not coprime");
+    }
+    if (d < 0) {
+      d += x;
+      if (d < 0) d += x;
+    } else if (d > x) {
+      d -= x;
+      if (d > x) d -= x;
+    }
+    return d;
+  }
+
+  // Returns 1/this % m, with m > 0.
+  int modInverse(int m) {
+    if (m <= 0) throw new RangeError.range(m, 1, null, "modulus");
+    if (m == 1) return 0;
+    int t = this;
+    if ((t < 0) || (t >= m)) t %= m;
+    if (t == 1) return 1;
+    if ((t == 0) || (t.isEven && m.isEven)) {
+      throw new Exception("Not coprime");
+    }
+    return _binaryGcd(m, t, true);
+  }
+
+  // Returns gcd of abs(this) and abs(other).
+  int gcd(int other) {
+    int x = this.abs();
+    int y = other.abs();
+    if (x == 0) return y;
+    if (y == 0) return x;
+    if ((x == 1) || (y == 1)) return 1;
+    return _binaryGcd(x, y, false);
+  }
+
+  int get hashCode => this;
+  int get _identityHashCode => this;
+
+  external int operator ~();
+  external int get bitLength;
+
+  /**
+   * The digits of '00', '01', ... '99' as a single array.
+   *
+   * Get the digits of `n`, with `0 <= n < 100`, as
+   * `_digitTable[n * 2]` and `_digitTable[n * 2 + 1]`.
+   */
+  static const _digitTable = const [
+    0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, //
+    0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, //
+    0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x31, 0x31, //
+    0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31, 0x35, //
+    0x31, 0x36, 0x31, 0x37, 0x31, 0x38, 0x31, 0x39, //
+    0x32, 0x30, 0x32, 0x31, 0x32, 0x32, 0x32, 0x33, //
+    0x32, 0x34, 0x32, 0x35, 0x32, 0x36, 0x32, 0x37, //
+    0x32, 0x38, 0x32, 0x39, 0x33, 0x30, 0x33, 0x31, //
+    0x33, 0x32, 0x33, 0x33, 0x33, 0x34, 0x33, 0x35, //
+    0x33, 0x36, 0x33, 0x37, 0x33, 0x38, 0x33, 0x39, //
+    0x34, 0x30, 0x34, 0x31, 0x34, 0x32, 0x34, 0x33, //
+    0x34, 0x34, 0x34, 0x35, 0x34, 0x36, 0x34, 0x37, //
+    0x34, 0x38, 0x34, 0x39, 0x35, 0x30, 0x35, 0x31, //
+    0x35, 0x32, 0x35, 0x33, 0x35, 0x34, 0x35, 0x35, //
+    0x35, 0x36, 0x35, 0x37, 0x35, 0x38, 0x35, 0x39, //
+    0x36, 0x30, 0x36, 0x31, 0x36, 0x32, 0x36, 0x33, //
+    0x36, 0x34, 0x36, 0x35, 0x36, 0x36, 0x36, 0x37, //
+    0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, //
+    0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, //
+    0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, //
+    0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, //
+    0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, //
+    0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, //
+    0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, //
+    0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39, //
+  ];
+
+  /**
+   * Result of int.toString for -99, -98, ..., 98, 99.
+   */
+  static const _smallLookupTable = const [
+    "-99", "-98", "-97", "-96", "-95", "-94", "-93", "-92", "-91", "-90", //
+    "-89", "-88", "-87", "-86", "-85", "-84", "-83", "-82", "-81", "-80", //
+    "-79", "-78", "-77", "-76", "-75", "-74", "-73", "-72", "-71", "-70", //
+    "-69", "-68", "-67", "-66", "-65", "-64", "-63", "-62", "-61", "-60", //
+    "-59", "-58", "-57", "-56", "-55", "-54", "-53", "-52", "-51", "-50", //
+    "-49", "-48", "-47", "-46", "-45", "-44", "-43", "-42", "-41", "-40", //
+    "-39", "-38", "-37", "-36", "-35", "-34", "-33", "-32", "-31", "-30", //
+    "-29", "-28", "-27", "-26", "-25", "-24", "-23", "-22", "-21", "-20", //
+    "-19", "-18", "-17", "-16", "-15", "-14", "-13", "-12", "-11", "-10", //
+    "-9", "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1", "0", //
+    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", //
+    "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", //
+    "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", //
+    "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", //
+    "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", //
+    "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", //
+    "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", //
+    "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", //
+    "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", //
+    "91", "92", "93", "94", "95", "96", "97", "98", "99" //
+  ];
+
+  // Powers of 10 above 1000000 are indistinguishable by eye.
+  static const int _POW_10_7 = 10000000;
+  static const int _POW_10_8 = 100000000;
+  static const int _POW_10_9 = 1000000000;
+
+  // Find the number of decimal digits in a positive smi.
+  // Never called with numbers < 100. These are handled before calling.
+  static int _positiveBase10Length(int smi) {
+    // A positive smi has length <= 19 if 63-bit,  <=10 if 31-bit.
+    // Avoid comparing a 31-bit smi to a non-smi.
+    if (smi < 1000) return 3;
+    if (smi < 10000) return 4;
+    if (smi < _POW_10_7) {
+      if (smi < 100000) return 5;
+      if (smi < 1000000) return 6;
+      return 7;
+    }
+    if (smi < _POW_10_8) return 8;
+    if (smi < _POW_10_9) return 9;
+    smi = smi ~/ _POW_10_9;
+    // Handle numbers < 100 before calling recursively.
+    if (smi < 10) return 10;
+    if (smi < 100) return 11;
+    return 9 + _positiveBase10Length(smi);
+  }
+
+  String toString() {
+    if (this < 100 && this > -100) {
+      // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the
+      // result type as `num`.
+      return _smallLookupTable[unsafeCast<int>(this + 99)];
+    }
+    if (this < 0) return _negativeToString(this);
+    // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++"
+    // Avoid expensive remainder operation by doing it on more than
+    // one digit at a time.
+    const int DIGIT_ZERO = 0x30;
+    int length = _positiveBase10Length(this);
+    _OneByteString result = _OneByteString._allocate(length);
+    int index = length - 1;
+    int smi = this;
+    do {
+      // Two digits at a time.
+      final int twoDigits = smi.remainder(100);
+      smi = smi ~/ 100;
+      int digitIndex = twoDigits * 2;
+      result._setAt(index, _digitTable[digitIndex + 1]);
+      result._setAt(index - 1, _digitTable[digitIndex]);
+      index -= 2;
+    } while (smi >= 100);
+    if (smi < 10) {
+      // Character code for '0'.
+      // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the
+      // result type as `num`.
+      result._setAt(index, DIGIT_ZERO + smi);
+    } else {
+      // No remainder for this case.
+      // Issue(https://dartbug.com/39639): The analyzer incorrectly reports the
+      // result type as `num`.
+      int digitIndex = smi * 2;
+      result._setAt(index, _digitTable[digitIndex + 1]);
+      result._setAt(index - 1, _digitTable[digitIndex]);
+    }
+    return result;
+  }
+
+  // Find the number of decimal digits in a negative smi.
+  // Never called with numbers > -100. These are handled before calling.
+  static int _negativeBase10Length(int negSmi) {
+    // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit.
+    // Avoid comparing a 31-bit smi to a non-smi.
+    if (negSmi > -1000) return 3;
+    if (negSmi > -10000) return 4;
+    if (negSmi > -_POW_10_7) {
+      if (negSmi > -100000) return 5;
+      if (negSmi > -1000000) return 6;
+      return 7;
+    }
+    if (negSmi > -_POW_10_8) return 8;
+    if (negSmi > -_POW_10_9) return 9;
+    negSmi = negSmi ~/ _POW_10_9;
+    // Handle numbers > -100 before calling recursively.
+    if (negSmi > -10) return 10;
+    if (negSmi > -100) return 11;
+    return 9 + _negativeBase10Length(negSmi);
+  }
+
+  // Convert a negative smi to a string.
+  // Doesn't negate the smi to avoid negating the most negative smi, which
+  // would become a non-smi.
+  static String _negativeToString(int negSmi) {
+    // Character code for '-'
+    const int MINUS_SIGN = 0x2d;
+    // Character code for '0'.
+    const int DIGIT_ZERO = 0x30;
+    if (negSmi > -10) {
+      return _OneByteString._allocate(2)
+        .._setAt(0, MINUS_SIGN)
+        .._setAt(1, DIGIT_ZERO - negSmi);
+    }
+    if (negSmi > -100) {
+      int digitIndex = 2 * -negSmi;
+      return _OneByteString._allocate(3)
+        .._setAt(0, MINUS_SIGN)
+        .._setAt(1, _digitTable[digitIndex])
+        .._setAt(2, _digitTable[digitIndex + 1]);
+    }
+    // Number of digits, not including minus.
+    int digitCount = _negativeBase10Length(negSmi);
+    _OneByteString result = _OneByteString._allocate(digitCount + 1);
+    result._setAt(0, MINUS_SIGN); // '-'.
+    int index = digitCount;
+    do {
+      int twoDigits = unsafeCast<int>(negSmi.remainder(100));
+      negSmi = negSmi ~/ 100;
+      int digitIndex = -twoDigits * 2;
+      result._setAt(index, _digitTable[digitIndex + 1]);
+      result._setAt(index - 1, _digitTable[digitIndex]);
+      index -= 2;
+    } while (negSmi <= -100);
+    if (negSmi > -10) {
+      result._setAt(index, DIGIT_ZERO - negSmi);
+    } else {
+      // No remainder necessary for this case.
+      int digitIndex = -negSmi * 2;
+      result._setAt(index, _digitTable[digitIndex + 1]);
+      result._setAt(index - 1, _digitTable[digitIndex]);
+    }
+    return result;
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/internal_patch.dart b/sdk/lib/_internal/wasm/lib/internal_patch.dart
new file mode 100644
index 0000000..3cd8846
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/internal_patch.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2022, 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 "dart:typed_data" show Uint8List;
+
+/// The returned string is a [_OneByteString] with uninitialized content.
+external String allocateOneByteString(int length);
+
+/// The [string] must be a [_OneByteString]. The [index] must be valid.
+external void writeIntoOneByteString(String string, int index, int codePoint);
+
+/// It is assumed that [from] is a native [Uint8List] class and [to] is a
+/// [_OneByteString]. The [fromStart] and [toStart] indices together with the
+/// [length] must specify ranges within the bounds of the list / string.
+void copyRangeFromUint8ListToOneByteString(
+    Uint8List from, String to, int fromStart, int toStart, int length) {
+  for (int i = 0; i < length; i++) {
+    writeIntoOneByteString(to, toStart + i, from[fromStart + i]);
+  }
+}
+
+/// The returned string is a [_TwoByteString] with uninitialized content.
+external String allocateTwoByteString(int length);
+
+/// The [string] must be a [_TwoByteString]. The [index] must be valid.
+external void writeIntoTwoByteString(String string, int index, int codePoint);
+
+// String accessors used to perform Dart<->JS string conversion
+
+@pragma("wasm:export", "\$stringLength")
+double _stringLength(String string) {
+  return string.length.toDouble();
+}
+
+@pragma("wasm:export", "\$stringRead")
+double _stringRead(String string, double index) {
+  return string.codeUnitAt(index.toInt()).toDouble();
+}
+
+@pragma("wasm:export", "\$stringAllocate1")
+String _stringAllocate1(double length) {
+  return allocateOneByteString(length.toInt());
+}
+
+@pragma("wasm:export", "\$stringWrite1")
+void _stringWrite1(String string, double index, double codePoint) {
+  writeIntoOneByteString(string, index.toInt(), codePoint.toInt());
+}
+
+@pragma("wasm:export", "\$stringAllocate2")
+String _stringAllocate2(double length) {
+  return allocateTwoByteString(length.toInt());
+}
+
+@pragma("wasm:export", "\$stringWrite2")
+void _stringWrite2(String string, double index, double codePoint) {
+  writeIntoTwoByteString(string, index.toInt(), codePoint.toInt());
+}
+
+const bool has63BitSmis = false;
+
+class Lists {
+  static void copy(List src, int srcStart, List dst, int dstStart, int count) {
+    // TODO(askesc): Intrinsify for efficient copying
+    if (srcStart < dstStart) {
+      for (int i = srcStart + count - 1, j = dstStart + count - 1;
+          i >= srcStart;
+          i--, j--) {
+        dst[j] = src[i];
+      }
+    } else {
+      for (int i = srcStart, j = dstStart; i < srcStart + count; i++, j++) {
+        dst[j] = src[i];
+      }
+    }
+  }
+}
+
+// This function can be used to skip implicit or explicit checked down casts in
+// the parts of the core library implementation where we know by construction
+// the type of a value.
+//
+// Important: this is unsafe and must be used with care.
+external T unsafeCast<T>(Object? v);
+
+// Thomas Wang 64-bit mix.
+// https://gist.github.com/badboy/6267743
+int mix64(int n) {
+  n = (~n) + (n << 21); // n = (n << 21) - n - 1;
+  n = n ^ (n >>> 24);
+  n = n * 265; // n = (n + (n << 3)) + (n << 8);
+  n = n ^ (n >>> 14);
+  n = n * 21; // n = (n + (n << 2)) + (n << 4);
+  n = n ^ (n >>> 28);
+  n = n + (n << 31);
+  return n;
+}
+
+external int floatToIntBits(double value);
+external double intBitsToFloat(int value);
+external int doubleToIntBits(double value);
+external double intBitsToDouble(int value);
+
+// Exported call stubs to enable JS to call Dart closures. Since all closure
+// parameters and returns are boxed (their Wasm type is #Top) the Wasm type of
+// the closure will be the same as with all parameters and returns as dynamic.
+// Thus, the unsafeCast succeeds, and as long as the passed argumnets have the
+// correct types, the argument casts inside the closure will also succeed.
+
+@pragma("wasm:export", "\$call0")
+dynamic _callClosure0(dynamic closure) {
+  return unsafeCast<dynamic Function()>(closure)();
+}
+
+@pragma("wasm:export", "\$call1")
+dynamic _callClosure1(dynamic closure, dynamic arg1) {
+  return unsafeCast<dynamic Function(dynamic)>(closure)(arg1);
+}
+
+@pragma("wasm:export", "\$call2")
+dynamic _callClosure2(dynamic closure, dynamic arg1, dynamic arg2) {
+  return unsafeCast<dynamic Function(dynamic, dynamic)>(closure)(arg1, arg2);
+}
+
+// Schedule a callback from JS via setTimeout.
+@pragma("wasm:import", "dart2wasm.scheduleCallback")
+external void scheduleCallback(double millis, dynamic Function() callback);
diff --git a/sdk/lib/_internal/wasm/lib/list.dart b/sdk/lib/_internal/wasm/lib/list.dart
new file mode 100644
index 0000000..13eeff3
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/list.dart
@@ -0,0 +1,223 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+@pragma("wasm:entry-point")
+abstract class _ListBase<E> extends ListBase<E> {
+  @pragma("wasm:entry-point")
+  int _length;
+  @pragma("wasm:entry-point")
+  WasmObjectArray<Object?> _data;
+
+  _ListBase(int length, int capacity)
+      : _length = length,
+        _data = WasmObjectArray<Object?>(capacity);
+
+  _ListBase._withData(this._length, this._data);
+
+  E operator [](int index) {
+    return unsafeCast(_data.read(index));
+  }
+
+  int get length => _length;
+
+  List<E> sublist(int start, [int? end]) {
+    final int listLength = this.length;
+    final int actualEnd = RangeError.checkValidRange(start, end, listLength);
+    int length = actualEnd - start;
+    if (length == 0) return <E>[];
+    return _GrowableList<E>(length)..setRange(0, length, this);
+  }
+
+  void forEach(f(E element)) {
+    final length = this.length;
+    for (int i = 0; i < length; i++) {
+      f(this[i]);
+    }
+  }
+
+  List<E> toList({bool growable: true}) {
+    return List.from(this, growable: growable);
+  }
+}
+
+@pragma("wasm:entry-point")
+abstract class _ModifiableList<E> extends _ListBase<E> {
+  _ModifiableList(int length, int capacity) : super(length, capacity);
+
+  _ModifiableList._withData(int length, WasmObjectArray<Object?> data)
+      : super._withData(length, data);
+
+  void operator []=(int index, E value) {
+    _data.write(index, value);
+  }
+
+  // List interface.
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    if (start < 0 || start > this.length) {
+      throw new RangeError.range(start, 0, this.length);
+    }
+    if (end < start || end > this.length) {
+      throw new RangeError.range(end, start, this.length);
+    }
+    int length = end - start;
+    if (length == 0) return;
+    if (identical(this, iterable)) {
+      Lists.copy(this, skipCount, this, start, length);
+    } else if (iterable is List<E>) {
+      Lists.copy(iterable, skipCount, this, start, length);
+    } else {
+      Iterator<E> it = iterable.iterator;
+      while (skipCount > 0) {
+        if (!it.moveNext()) return;
+        skipCount--;
+      }
+      for (int i = start; i < end; i++) {
+        if (!it.moveNext()) return;
+        this[i] = it.current;
+      }
+    }
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    if (index < 0 || index > this.length) {
+      throw new RangeError.range(index, 0, this.length, "index");
+    }
+    List<E> iterableAsList;
+    if (identical(this, iterable)) {
+      iterableAsList = this;
+    } else if (iterable is List<E>) {
+      iterableAsList = iterable;
+    } else {
+      for (var value in iterable) {
+        this[index++] = value;
+      }
+      return;
+    }
+    int length = iterableAsList.length;
+    if (index + length > this.length) {
+      throw new RangeError.range(index + length, 0, this.length);
+    }
+    Lists.copy(iterableAsList, 0, this, index, length);
+  }
+}
+
+@pragma("wasm:entry-point")
+class _List<E> extends _ModifiableList<E> with FixedLengthListMixin<E> {
+  _List._(int length) : super(length, length);
+
+  factory _List(int length) => _List._(length);
+
+  // Specialization of List.empty constructor for growable == false.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  factory _List.empty() => _List<E>(0);
+
+  // Specialization of List.filled constructor for growable == false.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  factory _List.filled(int length, E fill) {
+    final result = _List<E>(length);
+    if (fill != null) {
+      for (int i = 0; i < result.length; i++) {
+        result[i] = fill;
+      }
+    }
+    return result;
+  }
+
+  // Specialization of List.generate constructor for growable == false.
+  // Used by pkg/vm/lib/transformations/list_factory_specializer.dart.
+  factory _List.generate(int length, E generator(int index)) {
+    final result = _List<E>(length);
+    for (int i = 0; i < result.length; ++i) {
+      result[i] = generator(i);
+    }
+    return result;
+  }
+
+  // Specialization of List.of constructor for growable == false.
+  factory _List.of(Iterable<E> elements) {
+    if (elements is _ListBase) {
+      return _List._ofListBase(unsafeCast(elements));
+    }
+    if (elements is EfficientLengthIterable) {
+      return _List._ofEfficientLengthIterable(unsafeCast(elements));
+    }
+    return _List._ofOther(elements);
+  }
+
+  factory _List._ofListBase(_ListBase<E> elements) {
+    final int length = elements.length;
+    final list = _List<E>(length);
+    for (int i = 0; i < length; i++) {
+      list[i] = elements[i];
+    }
+    return list;
+  }
+
+  factory _List._ofEfficientLengthIterable(
+      EfficientLengthIterable<E> elements) {
+    final int length = elements.length;
+    final list = _List<E>(length);
+    if (length > 0) {
+      int i = 0;
+      for (var element in elements) {
+        list[i++] = element;
+      }
+      if (i != length) throw ConcurrentModificationError(elements);
+    }
+    return list;
+  }
+
+  factory _List._ofOther(Iterable<E> elements) {
+    // The static type of `makeListFixedLength` is `List<E>`, not `_List<E>`,
+    // but we know that is what it does.  `makeListFixedLength` is too generally
+    // typed since it is available on the web platform which has different
+    // system List types.
+    return unsafeCast(makeListFixedLength(_GrowableList<E>._ofOther(elements)));
+  }
+
+  Iterator<E> get iterator {
+    return new _FixedSizeListIterator<E>(this);
+  }
+}
+
+@pragma("wasm:entry-point")
+class _ImmutableList<E> extends _ListBase<E> with UnmodifiableListMixin<E> {
+  factory _ImmutableList._uninstantiable() {
+    throw new UnsupportedError(
+        "_ImmutableList can only be allocated by the runtime");
+  }
+
+  Iterator<E> get iterator {
+    return new _FixedSizeListIterator<E>(this);
+  }
+}
+
+// Iterator for lists with fixed size.
+class _FixedSizeListIterator<E> implements Iterator<E> {
+  final _ListBase<E> _list;
+  final int _length; // Cache list length for faster access.
+  int _index;
+  E? _current;
+
+  _FixedSizeListIterator(_ListBase<E> list)
+      : _list = list,
+        _length = list.length,
+        _index = 0 {
+    assert(list is _List<E> || list is _ImmutableList<E>);
+  }
+
+  E get current => _current as E;
+
+  bool moveNext() {
+    if (_index >= _length) {
+      _current = null;
+      return false;
+    }
+    _current = unsafeCast(_list._data.read(_index));
+    _index++;
+    return true;
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/math_patch.dart b/sdk/lib/_internal/wasm/lib/math_patch.dart
new file mode 100644
index 0000000..b26fd6d
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/math_patch.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2022, 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 "dart:_internal" show mix64, patch;
+
+import "dart:typed_data" show Uint32List;
+
+/// There are no parts of this patch library.
+
+@patch
+T min<T extends num>(T a, T b) {
+  if (a > b) return b;
+  if (a < b) return a;
+  if (b is double) {
+    // Special case for NaN and -0.0. If one argument is NaN return NaN.
+    // [min] must also distinguish between -0.0 and 0.0.
+    if (a is double) {
+      if (a == 0.0) {
+        // a is either 0.0 or -0.0. b is either 0.0, -0.0 or NaN.
+        // The following returns -0.0 if either a or b is -0.0, and it
+        // returns NaN if b is NaN.
+        num n = (a + b) * a * b;
+        return n as T;
+      }
+    }
+    // Check for NaN and b == -0.0.
+    if (a == 0 && b.isNegative || b.isNaN) return b;
+    return a;
+  }
+  return a;
+}
+
+@patch
+T max<T extends num>(T a, T b) {
+  if (a > b) return a;
+  if (a < b) return b;
+  if (b is double) {
+    // Special case for NaN and -0.0. If one argument is NaN return NaN.
+    // [max] must also distinguish between -0.0 and 0.0.
+    if (a is double) {
+      if (a == 0.0) {
+        // a is either 0.0 or -0.0. b is either 0.0, -0.0, or NaN.
+        // The following returns 0.0 if either a or b is 0.0, and it
+        // returns NaN if b is NaN.
+        num n = a + b;
+        return n as T;
+      }
+    }
+    // Check for NaN.
+    if (b.isNaN) return b;
+    return a;
+  }
+  // max(-0.0, 0) must return 0.
+  if (b == 0 && a.isNegative) return b;
+  return a;
+}
+
+// If [x] is an [int] and [exponent] is a non-negative [int], the result is
+// an [int], otherwise the result is a [double].
+@patch
+num pow(num x, num exponent) {
+  if ((x is int) && (exponent is int) && (exponent >= 0)) {
+    return _intPow(x, exponent);
+  }
+  return _doublePow(x.toDouble(), exponent.toDouble());
+}
+
+@pragma("wasm:import", "Math.pow")
+external double _doublePow(double base, double exponent);
+
+int _intPow(int base, int exponent) {
+  // Exponentiation by squaring.
+  int result = 1;
+  while (exponent != 0) {
+    if ((exponent & 1) == 1) {
+      result *= base;
+    }
+    exponent >>= 1;
+    // Skip unnecessary operation (can overflow to Mint).
+    if (exponent != 0) {
+      base *= base;
+    }
+  }
+  return result;
+}
+
+@patch
+double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
+@patch
+double sin(num radians) => _sin(radians.toDouble());
+@patch
+double cos(num radians) => _cos(radians.toDouble());
+@patch
+double tan(num radians) => _tan(radians.toDouble());
+@patch
+double acos(num x) => _acos(x.toDouble());
+@patch
+double asin(num x) => _asin(x.toDouble());
+@patch
+double atan(num x) => _atan(x.toDouble());
+@patch
+double sqrt(num x) => _sqrt(x.toDouble());
+@patch
+double exp(num x) => _exp(x.toDouble());
+@patch
+double log(num x) => _log(x.toDouble());
+
+@pragma("wasm:import", "Math.atan2")
+external double _atan2(double a, double b);
+@pragma("wasm:import", "Math.sin")
+external double _sin(double x);
+@pragma("wasm:import", "Math.cos")
+external double _cos(double x);
+@pragma("wasm:import", "Math.tan")
+external double _tan(double x);
+@pragma("wasm:import", "Math.acos")
+external double _acos(double x);
+@pragma("wasm:import", "Math.asin")
+external double _asin(double x);
+@pragma("wasm:import", "Math.atan")
+external double _atan(double x);
+@pragma("wasm:import", "Math.sqrt")
+external double _sqrt(double x);
+@pragma("wasm:import", "Math.exp")
+external double _exp(double x);
+@pragma("wasm:import", "Math.log")
+external double _log(double x);
+
+// TODO(iposva): Handle patch methods within a patch class correctly.
+@patch
+class Random {
+  static final Random _secureRandom = _SecureRandom();
+
+  @patch
+  factory Random([int? seed]) {
+    var state = _Random._setupSeed((seed == null) ? _Random._nextSeed() : seed);
+    // Crank a couple of times to distribute the seed bits a bit further.
+    return new _Random._withState(state)
+      .._nextState()
+      .._nextState()
+      .._nextState()
+      .._nextState();
+  }
+
+  @patch
+  factory Random.secure() => _secureRandom;
+}
+
+class _Random implements Random {
+  // Internal state of the random number generator.
+  int _state;
+
+  int get _stateLow => _state & 0xFFFFFFFF;
+  int get _stateHigh => _state >>> 32;
+
+  _Random._withState(this._state);
+
+  // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32.
+  // http://en.wikipedia.org/wiki/Multiply-with-carry
+  // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1.
+
+  // Implements:
+  //   const _A = 0xffffda61;
+  //   var state =
+  //       ((_A * (_state[_kSTATE_LO])) + _state[_kSTATE_HI]) & ((1 << 64) - 1);
+  //   _state[_kSTATE_LO] = state & ((1 << 32) - 1);
+  //   _state[_kSTATE_HI] = state >> 32;
+  // This is a native to prevent 64-bit operations in Dart, which
+  // fail with --throw_on_javascript_int_overflow.
+  // TODO(regis): Implement in Dart and remove Random_nextState in math.cc.
+  void _nextState() {
+    const _A = 0xffffda61;
+    _state = _A * _stateLow + _stateHigh;
+  }
+
+  int nextInt(int max) {
+    if (max <= 0 || max > _POW2_32) {
+      throw new RangeError.range(
+          max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
+    }
+    if ((max & -max) == max) {
+      // Fast case for powers of two.
+      _nextState();
+      return _state & (max - 1);
+    }
+
+    int rnd32;
+    int result;
+    do {
+      _nextState();
+      rnd32 = _stateLow;
+      result = rnd32 % max;
+    } while ((rnd32 - result + max) > _POW2_32);
+    return result;
+  }
+
+  double nextDouble() {
+    return ((nextInt(1 << 26) * _POW2_27_D) + nextInt(1 << 27)) / _POW2_53_D;
+  }
+
+  bool nextBool() {
+    return nextInt(2) == 0;
+  }
+
+  // Constants used by the algorithm.
+  static const _POW2_32 = 1 << 32;
+  static const _POW2_53_D = 1.0 * (1 << 53);
+  static const _POW2_27_D = 1.0 * (1 << 27);
+
+  // Use a singleton Random object to get a new seed if no seed was passed.
+  static final _prng = new _Random._withState(_initialSeed());
+
+  static int _setupSeed(int seed) => mix64(seed);
+
+  // TODO: Make this actually random
+  static int _initialSeed() => 0xCAFEBABEDEADBEEF;
+
+  static int _nextSeed() {
+    // Trigger the PRNG once to change the internal state.
+    _prng._nextState();
+    return _prng._stateLow;
+  }
+}
+
+class _SecureRandom implements Random {
+  _SecureRandom() {
+    // Throw early in constructor if entropy source is not hooked up.
+    _getBytes(1);
+  }
+
+  // Return count bytes of entropy as a positive integer; count <= 8.
+  external static int _getBytes(int count);
+
+  int nextInt(int max) {
+    RangeError.checkValueInInterval(
+        max, 1, _POW2_32, "max", "Must be positive and <= 2^32");
+    final byteCount = ((max - 1).bitLength + 7) >> 3;
+    if (byteCount == 0) {
+      return 0; // Not random if max == 1.
+    }
+    var rnd;
+    var result;
+    do {
+      rnd = _getBytes(byteCount);
+      result = rnd % max;
+    } while ((rnd - result + max) > (1 << (byteCount << 3)));
+    return result;
+  }
+
+  double nextDouble() {
+    return (_getBytes(7) >> 3) / _POW2_53_D;
+  }
+
+  bool nextBool() {
+    return _getBytes(1).isEven;
+  }
+
+  // Constants used by the algorithm.
+  static const _POW2_32 = 1 << 32;
+  static const _POW2_53_D = 1.0 * (1 << 53);
+}
diff --git a/sdk/lib/_internal/wasm/lib/object_patch.dart b/sdk/lib/_internal/wasm/lib/object_patch.dart
new file mode 100644
index 0000000..d38ca14
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/object_patch.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+// Access hidden identity hash code field
+external int _getHash(Object obj);
+external void _setHash(Object obj, int hash);
+
+@patch
+class Object {
+  @patch
+  external bool operator ==(Object other);
+
+  // Random number generator used to generate identity hash codes.
+  static final _hashCodeRnd = new Random();
+
+  static int _objectHashCode(Object obj) {
+    var result = _getHash(obj);
+    if (result == 0) {
+      // We want the hash to be a Smi value greater than 0.
+      do {
+        result = _hashCodeRnd.nextInt(0x40000000);
+      } while (result == 0);
+
+      _setHash(obj, result);
+      return result;
+    }
+    return result;
+  }
+
+  @patch
+  int get hashCode => _objectHashCode(this);
+  int get _identityHashCode => _objectHashCode(this);
+
+  @patch
+  String toString() => _toString(this);
+  // A statically dispatched version of Object.toString.
+  static String _toString(obj) => "Instance of '${obj.runtimeType}'";
+
+  @patch
+  dynamic noSuchMethod(Invocation invocation) {
+    throw new NoSuchMethodError.withInvocation(this, invocation);
+  }
+
+  @patch
+  external Type get runtimeType;
+}
diff --git a/sdk/lib/_internal/wasm/lib/patch.dart b/sdk/lib/_internal/wasm/lib/patch.dart
new file mode 100644
index 0000000..f69ddc4
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/patch.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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.
+
+class _Patch {
+  const _Patch();
+}
+
+const _Patch patch = const _Patch();
diff --git a/sdk/lib/_internal/wasm/lib/print_patch.dart b/sdk/lib/_internal/wasm/lib/print_patch.dart
new file mode 100644
index 0000000..e08b7e2
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/print_patch.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2022, 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.
+
+// part of "internal_patch.dart";
+
+@patch
+@pragma("wasm:import", "dart2wasm.printToConsole")
+external void printToConsole(String line);
diff --git a/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart b/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
new file mode 100644
index 0000000..ac22cba
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
@@ -0,0 +1,212 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+// This file is identical to the VM `string_buffer_patch.dart` except for the
+// implementation of `StringBuffer._create`.
+// TODO(askesc): Share this file with the VM when the patching mechanism gains
+// support for patching an external member from a patch in a separate patch.
+
+@patch
+class StringBuffer {
+  static const int _BUFFER_SIZE = 64;
+  static const int _PARTS_TO_COMPACT = 128;
+  static const int _PARTS_TO_COMPACT_SIZE_LIMIT = _PARTS_TO_COMPACT * 8;
+
+  /**
+   * When strings are written to the string buffer, we add them to a
+   * list of string parts.
+   */
+  List<String>? _parts;
+
+  /**
+    * Total number of code units in the string parts. Does not include
+    * the code units added to the buffer.
+    */
+  int _partsCodeUnits = 0;
+
+  /**
+   * To preserve memory, we sometimes compact the parts. This combines
+   * several smaller parts into a single larger part to cut down on the
+   * cost that comes from the per-object memory overhead. We keep track
+   * of the last index where we ended our compaction and the number of
+   * code units added since the last compaction.
+   */
+  int _partsCompactionIndex = 0;
+  int _partsCodeUnitsSinceCompaction = 0;
+
+  /**
+   * The buffer is used to build up a string from code units. It is
+   * used when writing short strings or individual char codes to the
+   * buffer. The buffer is allocated on demand.
+   */
+  Uint16List? _buffer;
+  int _bufferPosition = 0;
+
+  /**
+   * Collects the approximate maximal magnitude of the code units added
+   * to the buffer.
+   *
+   * The value of each added code unit is or'ed with this variable, so the
+   * most significant bit set in any code unit is also set in this value.
+   * If below 256, the string in the buffer is a Latin-1 string.
+   */
+  int _bufferCodeUnitMagnitude = 0;
+
+  /// Creates the string buffer with an initial content.
+  @patch
+  StringBuffer([Object content = ""]) {
+    write(content);
+  }
+
+  @patch
+  int get length => _partsCodeUnits + _bufferPosition;
+
+  @patch
+  void write(Object? obj) {
+    String str = "$obj";
+    if (str.isEmpty) return;
+    _consumeBuffer();
+    _addPart(str);
+  }
+
+  @patch
+  void writeCharCode(int charCode) {
+    if (charCode <= 0xFFFF) {
+      if (charCode < 0) {
+        throw new RangeError.range(charCode, 0, 0x10FFFF);
+      }
+      _ensureCapacity(1);
+      final localBuffer = _buffer!;
+      localBuffer[_bufferPosition++] = charCode;
+      _bufferCodeUnitMagnitude |= charCode;
+    } else {
+      if (charCode > 0x10FFFF) {
+        throw new RangeError.range(charCode, 0, 0x10FFFF);
+      }
+      _ensureCapacity(2);
+      int bits = charCode - 0x10000;
+      final localBuffer = _buffer!;
+      localBuffer[_bufferPosition++] = 0xD800 | (bits >> 10);
+      localBuffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
+      _bufferCodeUnitMagnitude |= 0xFFFF;
+    }
+  }
+
+  @patch
+  void writeAll(Iterable objects, [String separator = ""]) {
+    Iterator iterator = objects.iterator;
+    if (!iterator.moveNext()) return;
+    if (separator.isEmpty) {
+      do {
+        write(iterator.current);
+      } while (iterator.moveNext());
+    } else {
+      write(iterator.current);
+      while (iterator.moveNext()) {
+        write(separator);
+        write(iterator.current);
+      }
+    }
+  }
+
+  @patch
+  void writeln([Object? obj = ""]) {
+    write(obj);
+    write("\n");
+  }
+
+  /** Makes the buffer empty. */
+  @patch
+  void clear() {
+    _parts = null;
+    _partsCodeUnits = _bufferPosition = _bufferCodeUnitMagnitude = 0;
+  }
+
+  /** Returns the contents of buffer as a string. */
+  @patch
+  String toString() {
+    _consumeBuffer();
+    final localParts = _parts;
+    return (_partsCodeUnits == 0 || localParts == null)
+        ? ""
+        : _StringBase._concatRange(localParts, 0, localParts.length);
+  }
+
+  /** Ensures that the buffer has enough capacity to add n code units. */
+  void _ensureCapacity(int n) {
+    final localBuffer = _buffer;
+    if (localBuffer == null) {
+      _buffer = new Uint16List(_BUFFER_SIZE);
+    } else if (_bufferPosition + n > localBuffer.length) {
+      _consumeBuffer();
+    }
+  }
+
+  /**
+   * Consumes the content of the buffer by turning it into a string
+   * and adding it as a part. After calling this the buffer position
+   * will be reset to zero.
+   */
+  void _consumeBuffer() {
+    if (_bufferPosition == 0) return;
+    bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF;
+    String str = _create(_buffer!, _bufferPosition, isLatin1);
+    _bufferPosition = _bufferCodeUnitMagnitude = 0;
+    _addPart(str);
+  }
+
+  /**
+   * Adds a new part to this string buffer and keeps track of how
+   * many code units are contained in the parts.
+   */
+  void _addPart(String str) {
+    final localParts = _parts;
+    int length = str.length;
+    _partsCodeUnits += length;
+    _partsCodeUnitsSinceCompaction += length;
+
+    if (localParts == null) {
+      // Empirically this is a good capacity to minimize total bytes allocated.
+      _parts = new _GrowableList.withCapacity(10)..add(str);
+    } else {
+      localParts.add(str);
+      int partsSinceCompaction = localParts.length - _partsCompactionIndex;
+      if (partsSinceCompaction == _PARTS_TO_COMPACT) {
+        _compact();
+      }
+    }
+  }
+
+  /**
+   * Compacts the last N parts if their average size allows us to save a
+   * lot of memory by turning them all into a single part.
+   */
+  void _compact() {
+    final localParts = _parts!;
+    if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) {
+      String compacted = _StringBase._concatRange(
+          localParts,
+          _partsCompactionIndex, // Start
+          _partsCompactionIndex + _PARTS_TO_COMPACT // End
+          );
+      localParts.length = localParts.length - _PARTS_TO_COMPACT;
+      localParts.add(compacted);
+    }
+    _partsCodeUnitsSinceCompaction = 0;
+    _partsCompactionIndex = localParts.length;
+  }
+
+  /**
+   * Create a [String] from the UFT-16 code units in buffer.
+   */
+  static String _create(Uint16List buffer, int length, bool isLatin1) {
+    if (isLatin1) {
+      return _StringBase._createOneByteString(buffer, 0, length);
+    } else {
+      return _TwoByteString._allocateFromTwoByteList(buffer, 0, length);
+    }
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/string_patch.dart b/sdk/lib/_internal/wasm/lib/string_patch.dart
new file mode 100644
index 0000000..a9c0222
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/string_patch.dart
@@ -0,0 +1,1391 @@
+// Copyright (c) 2022, 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.
+
+// part of "core_patch.dart";
+
+// Much of this patch file is similar to the VM `string_patch.dart`. It may make
+// sense to share some of the code when the patching mechanism supports patching
+// the same class in multiple patch files.
+
+const int _maxAscii = 0x7f;
+const int _maxLatin1 = 0xff;
+const int _maxUtf16 = 0xffff;
+const int _maxUnicode = 0x10ffff;
+
+@patch
+class String {
+  @patch
+  factory String.fromCharCodes(Iterable<int> charCodes,
+      [int start = 0, int? end]) {
+    return _StringBase.createFromCharCodes(charCodes, start, end, null);
+  }
+
+  @patch
+  factory String.fromCharCode(int charCode) {
+    if (charCode >= 0) {
+      if (charCode <= 0xff) {
+        return _OneByteString._allocate(1).._setAt(0, charCode);
+      }
+      if (charCode <= 0xffff) {
+        return _TwoByteString._allocate(1).._setAt(0, charCode);
+      }
+      if (charCode <= 0x10ffff) {
+        var low = 0xDC00 | (charCode & 0x3ff);
+        int bits = charCode - 0x10000;
+        var high = 0xD800 | (bits >> 10);
+        return _StringBase._createFromCodePoints(
+            new _List(2)
+              ..[0] = high
+              ..[1] = low,
+            0,
+            2);
+      }
+    }
+    throw new RangeError.range(charCode, 0, 0x10ffff);
+  }
+
+  @patch
+  external const factory String.fromEnvironment(String name,
+      {String defaultValue = ""});
+
+  bool get _isOneByte;
+  String _substringUnchecked(int startIndex, int endIndex);
+}
+
+/**
+ * [_StringBase] contains common methods used by concrete String
+ * implementations, e.g., _OneByteString.
+ */
+abstract class _StringBase implements String {
+  bool _isWhitespace(int codeUnit);
+
+  // Constants used by replaceAll encoding of string slices between matches.
+  // A string slice (start+length) is encoded in a single Smi to save memory
+  // overhead in the common case.
+  // We use fewer bits for length (11 bits) than for the start index (19+ bits).
+  // For long strings, it's possible to have many large indices,
+  // but it's unlikely to have many long lengths since slices don't overlap.
+  // If there are few matches in a long string, then there are few long slices,
+  // and if there are many matches, there'll likely be many short slices.
+  //
+  // Encoding is: 0((start << _lengthBits) | length)
+
+  // Number of bits used by length.
+  // This is the shift used to encode and decode the start index.
+  static const int _lengthBits = 11;
+  // The maximal allowed length value in an encoded slice.
+  static const int _maxLengthValue = (1 << _lengthBits) - 1;
+  // Mask of length in encoded smi value.
+  static const int _lengthMask = _maxLengthValue;
+  static const int _startBits = _maxUnsignedSmiBits - _lengthBits;
+  // Maximal allowed start index value in an encoded slice.
+  static const int _maxStartValue = (1 << _startBits) - 1;
+  // We pick 30 as a safe lower bound on available bits in a negative smi.
+  // TODO(lrn): Consider allowing more bits for start on 64-bit systems.
+  static const int _maxUnsignedSmiBits = 30;
+
+  // For longer strings, calling into C++ to create the result of a
+  // [replaceAll] is faster than [_joinReplaceAllOneByteResult].
+  // TODO(lrn): See if this limit can be tweaked.
+  static const int _maxJoinReplaceOneByteStringLength = 500;
+
+  _StringBase._();
+
+  int get hashCode {
+    int hash = _getHash(this);
+    if (hash != 0) return hash;
+    hash = _computeHashCode();
+    _setHash(this, hash);
+    return hash;
+  }
+
+  int _computeHashCode();
+
+  int get _identityHashCode => hashCode;
+
+  bool get _isOneByte {
+    // Alternatively return false and override it on one-byte string classes.
+    return this is _OneByteString;
+  }
+
+  /**
+   * Create the most efficient string representation for specified
+   * [charCodes].
+   *
+   * Only uses the character codes between index [start] and index [end] of
+   * `charCodes`. They must satisfy `0 <= start <= end <= charCodes.length`.
+   *
+   * The [limit] is an upper limit on the character codes in the iterable.
+   * It's `null` if unknown.
+   */
+  static String createFromCharCodes(
+      Iterable<int> charCodes, int start, int? end, int? limit) {
+    // TODO(srdjan): Also skip copying of wide typed arrays.
+    if (charCodes is Uint8List) {
+      final actualEnd =
+          RangeError.checkValidRange(start, end, charCodes.length);
+      return _createOneByteString(charCodes, start, actualEnd - start);
+    } else if (charCodes is! Uint16List) {
+      return _createStringFromIterable(charCodes, start, end);
+    }
+    final int codeCount = charCodes.length;
+    final actualEnd = RangeError.checkValidRange(start, end, codeCount);
+    final len = actualEnd - start;
+    if (len == 0) return "";
+
+    final typedCharCodes = unsafeCast<List<int>>(charCodes);
+
+    final int actualLimit =
+        limit ?? _scanCodeUnits(typedCharCodes, start, actualEnd);
+    if (actualLimit < 0) {
+      throw new ArgumentError(typedCharCodes);
+    }
+    if (actualLimit <= _maxLatin1) {
+      return _createOneByteString(typedCharCodes, start, len);
+    }
+    if (actualLimit <= _maxUtf16) {
+      return _TwoByteString._allocateFromTwoByteList(
+          typedCharCodes, start, actualEnd);
+    }
+    // TODO(lrn): Consider passing limit to _createFromCodePoints, because
+    // the function is currently fully generic and doesn't know that its
+    // charCodes are not all Latin-1 or Utf-16.
+    return _createFromCodePoints(typedCharCodes, start, actualEnd);
+  }
+
+  static int _scanCodeUnits(List<int> charCodes, int start, int end) {
+    int bits = 0;
+    for (int i = start; i < end; i++) {
+      int code = charCodes[i];
+      bits |= code;
+    }
+    return bits;
+  }
+
+  static String _createStringFromIterable(
+      Iterable<int> charCodes, int start, int? end) {
+    // Treat charCodes as Iterable.
+    if (charCodes is EfficientLengthIterable) {
+      int length = charCodes.length;
+      final endVal = RangeError.checkValidRange(start, end, length);
+      final charCodeList = new List<int>.from(
+          charCodes.take(endVal).skip(start),
+          growable: false);
+      return createFromCharCodes(charCodeList, 0, charCodeList.length, null);
+    }
+    // Don't know length of iterable, so iterate and see if all the values
+    // are there.
+    if (start < 0) throw new RangeError.range(start, 0, charCodes.length);
+    var it = charCodes.iterator;
+    for (int i = 0; i < start; i++) {
+      if (!it.moveNext()) {
+        throw new RangeError.range(start, 0, i);
+      }
+    }
+    List<int> charCodeList;
+    int bits = 0; // Bitwise-or of all char codes in list.
+    final endVal = end;
+    if (endVal == null) {
+      var list = <int>[];
+      while (it.moveNext()) {
+        int code = it.current;
+        bits |= code;
+        list.add(code);
+      }
+      charCodeList = makeListFixedLength<int>(list);
+    } else {
+      if (endVal < start) {
+        throw new RangeError.range(endVal, start, charCodes.length);
+      }
+      int len = endVal - start;
+      charCodeList = new List<int>.generate(len, (int i) {
+        if (!it.moveNext()) {
+          throw new RangeError.range(endVal, start, start + i);
+        }
+        int code = it.current;
+        bits |= code;
+        return code;
+      });
+    }
+    int length = charCodeList.length;
+    if (bits < 0) {
+      throw new ArgumentError(charCodes);
+    }
+    bool isOneByteString = (bits <= _maxLatin1);
+    if (isOneByteString) {
+      return _createOneByteString(charCodeList, 0, length);
+    }
+    return createFromCharCodes(charCodeList, 0, length, bits);
+  }
+
+  // Inlining is disabled as a workaround to http://dartbug.com/37800.
+
+  static String _createOneByteString(List<int> charCodes, int start, int len) {
+    // It's always faster to do this in Dart than to call into the runtime.
+    var s = _OneByteString._allocate(len);
+
+    // Special case for native Uint8 typed arrays.
+    if (charCodes is Uint8List) {
+      copyRangeFromUint8ListToOneByteString(charCodes, s, start, 0, len);
+      return s;
+    }
+
+    // Fall through to normal case.
+    for (int i = 0; i < len; i++) {
+      s._setAt(i, charCodes[start + i]);
+    }
+    return s;
+  }
+
+  external static String _createFromCodePoints(
+      List<int> codePoints, int start, int end);
+
+  String operator [](int index) => String.fromCharCode(codeUnitAt(index));
+
+  int codeUnitAt(int index); // Implemented in the subclasses.
+
+  int get length; // Implemented in the subclasses.
+
+  bool get isEmpty {
+    return this.length == 0;
+  }
+
+  bool get isNotEmpty => !isEmpty;
+
+  String operator +(String other) => _interpolate([this, other]);
+
+  String toString() {
+    return this;
+  }
+
+  bool operator ==(Object other) {
+    if (identical(this, other)) {
+      return true;
+    }
+    if (other is String && this.length == other.length) {
+      final len = this.length;
+      for (int i = 0; i < len; i++) {
+        if (this.codeUnitAt(i) != other.codeUnitAt(i)) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+
+  int compareTo(String other) {
+    int thisLength = this.length;
+    int otherLength = other.length;
+    int len = (thisLength < otherLength) ? thisLength : otherLength;
+    for (int i = 0; i < len; i++) {
+      int thisCodeUnit = this.codeUnitAt(i);
+      int otherCodeUnit = other.codeUnitAt(i);
+      if (thisCodeUnit < otherCodeUnit) {
+        return -1;
+      }
+      if (thisCodeUnit > otherCodeUnit) {
+        return 1;
+      }
+    }
+    if (thisLength < otherLength) return -1;
+    if (thisLength > otherLength) return 1;
+    return 0;
+  }
+
+  bool _substringMatches(int start, String other) {
+    if (other.isEmpty) return true;
+    final len = other.length;
+    if ((start < 0) || (start + len > this.length)) {
+      return false;
+    }
+    for (int i = 0; i < len; i++) {
+      if (this.codeUnitAt(i + start) != other.codeUnitAt(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  bool endsWith(String other) {
+    return _substringMatches(this.length - other.length, other);
+  }
+
+  bool startsWith(Pattern pattern, [int index = 0]) {
+    if ((index < 0) || (index > this.length)) {
+      throw new RangeError.range(index, 0, this.length);
+    }
+    if (pattern is String) {
+      return _substringMatches(index, pattern);
+    }
+    return pattern.matchAsPrefix(this, index) != null;
+  }
+
+  int indexOf(Pattern pattern, [int start = 0]) {
+    if ((start < 0) || (start > this.length)) {
+      throw new RangeError.range(start, 0, this.length, "start");
+    }
+    if (pattern is String) {
+      String other = pattern;
+      int maxIndex = this.length - other.length;
+      // TODO: Use an efficient string search (e.g. BMH).
+      for (int index = start; index <= maxIndex; index++) {
+        if (_substringMatches(index, other)) {
+          return index;
+        }
+      }
+      return -1;
+    }
+    for (int i = start; i <= this.length; i++) {
+      // TODO(11276); This has quadratic behavior because matchAsPrefix tries
+      // to find a later match too. Optimize matchAsPrefix to avoid this.
+      if (pattern.matchAsPrefix(this, i) != null) return i;
+    }
+    return -1;
+  }
+
+  int lastIndexOf(Pattern pattern, [int? start]) {
+    if (start == null) {
+      start = this.length;
+    } else if (start < 0 || start > this.length) {
+      throw new RangeError.range(start, 0, this.length);
+    }
+    if (pattern is String) {
+      String other = pattern;
+      int maxIndex = this.length - other.length;
+      if (maxIndex < start) start = maxIndex;
+      for (int index = start; index >= 0; index--) {
+        if (_substringMatches(index, other)) {
+          return index;
+        }
+      }
+      return -1;
+    }
+    for (int i = start; i >= 0; i--) {
+      // TODO(11276); This has quadratic behavior because matchAsPrefix tries
+      // to find a later match too. Optimize matchAsPrefix to avoid this.
+      if (pattern.matchAsPrefix(this, i) != null) return i;
+    }
+    return -1;
+  }
+
+  String substring(int startIndex, [int? endIndex]) {
+    endIndex = RangeError.checkValidRange(startIndex, endIndex, this.length);
+    return _substringUnchecked(startIndex, endIndex);
+  }
+
+  String _substringUnchecked(int startIndex, int endIndex) {
+    assert((startIndex >= 0) && (startIndex <= this.length));
+    assert((endIndex >= 0) && (endIndex <= this.length));
+    assert(startIndex <= endIndex);
+
+    if (startIndex == endIndex) {
+      return "";
+    }
+    if ((startIndex == 0) && (endIndex == this.length)) {
+      return this;
+    }
+    if ((startIndex + 1) == endIndex) {
+      return this[startIndex];
+    }
+    return _substringUncheckedNative(startIndex, endIndex);
+  }
+
+  external String _substringUncheckedNative(int startIndex, int endIndex);
+
+  // Checks for one-byte whitespaces only.
+  static bool _isOneByteWhitespace(int codeUnit) {
+    if (codeUnit <= 32) {
+      return ((codeUnit == 32) || // Space.
+          ((codeUnit <= 13) && (codeUnit >= 9))); // CR, LF, TAB, etc.
+    }
+    return (codeUnit == 0x85) || (codeUnit == 0xA0); // NEL, NBSP.
+  }
+
+  // Characters with Whitespace property (Unicode 6.3).
+  // 0009..000D    ; White_Space # Cc       <control-0009>..<control-000D>
+  // 0020          ; White_Space # Zs       SPACE
+  // 0085          ; White_Space # Cc       <control-0085>
+  // 00A0          ; White_Space # Zs       NO-BREAK SPACE
+  // 1680          ; White_Space # Zs       OGHAM SPACE MARK
+  // 2000..200A    ; White_Space # Zs       EN QUAD..HAIR SPACE
+  // 2028          ; White_Space # Zl       LINE SEPARATOR
+  // 2029          ; White_Space # Zp       PARAGRAPH SEPARATOR
+  // 202F          ; White_Space # Zs       NARROW NO-BREAK SPACE
+  // 205F          ; White_Space # Zs       MEDIUM MATHEMATICAL SPACE
+  // 3000          ; White_Space # Zs       IDEOGRAPHIC SPACE
+  //
+  // BOM: 0xFEFF
+  static bool _isTwoByteWhitespace(int codeUnit) {
+    if (codeUnit <= 32) {
+      return (codeUnit == 32) || ((codeUnit <= 13) && (codeUnit >= 9));
+    }
+    if (codeUnit < 0x85) return false;
+    if ((codeUnit == 0x85) || (codeUnit == 0xA0)) return true;
+    return (codeUnit <= 0x200A)
+        ? ((codeUnit == 0x1680) || (0x2000 <= codeUnit))
+        : ((codeUnit == 0x2028) ||
+            (codeUnit == 0x2029) ||
+            (codeUnit == 0x202F) ||
+            (codeUnit == 0x205F) ||
+            (codeUnit == 0x3000) ||
+            (codeUnit == 0xFEFF));
+  }
+
+  int _firstNonWhitespace() {
+    final len = this.length;
+    int first = 0;
+    for (; first < len; first++) {
+      if (!_isWhitespace(this.codeUnitAt(first))) {
+        break;
+      }
+    }
+    return first;
+  }
+
+  int _lastNonWhitespace() {
+    int last = this.length - 1;
+    for (; last >= 0; last--) {
+      if (!_isWhitespace(this.codeUnitAt(last))) {
+        break;
+      }
+    }
+    return last;
+  }
+
+  String trim() {
+    final len = this.length;
+    int first = _firstNonWhitespace();
+    if (len == first) {
+      // String contains only whitespaces.
+      return "";
+    }
+    int last = _lastNonWhitespace() + 1;
+    if ((first == 0) && (last == len)) {
+      // Returns this string since it does not have leading or trailing
+      // whitespaces.
+      return this;
+    }
+    return _substringUnchecked(first, last);
+  }
+
+  String trimLeft() {
+    final len = this.length;
+    int first = 0;
+    for (; first < len; first++) {
+      if (!_isWhitespace(this.codeUnitAt(first))) {
+        break;
+      }
+    }
+    if (len == first) {
+      // String contains only whitespaces.
+      return "";
+    }
+    if (first == 0) {
+      // Returns this string since it does not have leading or trailing
+      // whitespaces.
+      return this;
+    }
+    return _substringUnchecked(first, len);
+  }
+
+  String trimRight() {
+    final len = this.length;
+    int last = len - 1;
+    for (; last >= 0; last--) {
+      if (!_isWhitespace(this.codeUnitAt(last))) {
+        break;
+      }
+    }
+    if (last == -1) {
+      // String contains only whitespaces.
+      return "";
+    }
+    if (last == (len - 1)) {
+      // Returns this string since it does not have trailing whitespaces.
+      return this;
+    }
+    return _substringUnchecked(0, last + 1);
+  }
+
+  String operator *(int times) {
+    if (times <= 0) return "";
+    if (times == 1) return this;
+    StringBuffer buffer = new StringBuffer(this);
+    for (int i = 1; i < times; i++) {
+      buffer.write(this);
+    }
+    return buffer.toString();
+  }
+
+  String padLeft(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    StringBuffer buffer = new StringBuffer();
+    for (int i = 0; i < delta; i++) {
+      buffer.write(padding);
+    }
+    buffer.write(this);
+    return buffer.toString();
+  }
+
+  String padRight(int width, [String padding = ' ']) {
+    int delta = width - this.length;
+    if (delta <= 0) return this;
+    StringBuffer buffer = new StringBuffer(this);
+    for (int i = 0; i < delta; i++) {
+      buffer.write(padding);
+    }
+    return buffer.toString();
+  }
+
+  bool contains(Pattern pattern, [int startIndex = 0]) {
+    if (pattern is String) {
+      if (startIndex < 0 || startIndex > this.length) {
+        throw new RangeError.range(startIndex, 0, this.length);
+      }
+      return indexOf(pattern, startIndex) >= 0;
+    }
+    return pattern.allMatches(this.substring(startIndex)).isNotEmpty;
+  }
+
+  String replaceFirst(Pattern pattern, String replacement,
+      [int startIndex = 0]) {
+    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
+    Iterator iterator = startIndex == 0
+        ? pattern.allMatches(this).iterator
+        : pattern.allMatches(this, startIndex).iterator;
+    if (!iterator.moveNext()) return this;
+    Match match = iterator.current;
+    return replaceRange(match.start, match.end, replacement);
+  }
+
+  String replaceRange(int start, int? end, String replacement) {
+    final length = this.length;
+    final localEnd = RangeError.checkValidRange(start, end, length);
+    bool replacementIsOneByte = replacement._isOneByte;
+    if (start == 0 && localEnd == length) return replacement;
+    int replacementLength = replacement.length;
+    int totalLength = start + (length - localEnd) + replacementLength;
+    if (replacementIsOneByte && this._isOneByte) {
+      var result = _OneByteString._allocate(totalLength);
+      int index = 0;
+      index = result._setRange(index, this, 0, start);
+      index = result._setRange(start, replacement, 0, replacementLength);
+      result._setRange(index, this, localEnd, length);
+      return result;
+    }
+    List slices = [];
+    _addReplaceSlice(slices, 0, start);
+    if (replacement.length > 0) slices.add(replacement);
+    _addReplaceSlice(slices, localEnd, length);
+    return _joinReplaceAllResult(
+        this, slices, totalLength, replacementIsOneByte);
+  }
+
+  static int _addReplaceSlice(List matches, int start, int end) {
+    int length = end - start;
+    if (length > 0) {
+      if (length <= _maxLengthValue && start <= _maxStartValue) {
+        matches.add(-((start << _lengthBits) | length));
+      } else {
+        matches.add(start);
+        matches.add(end);
+      }
+    }
+    return length;
+  }
+
+  String replaceAll(Pattern pattern, String replacement) {
+    int startIndex = 0;
+    // String fragments that replace the prefix [this] up to [startIndex].
+    List matches = [];
+    int length = 0; // Length of all fragments.
+    int replacementLength = replacement.length;
+
+    if (replacementLength == 0) {
+      for (Match match in pattern.allMatches(this)) {
+        length += _addReplaceSlice(matches, startIndex, match.start);
+        startIndex = match.end;
+      }
+    } else {
+      for (Match match in pattern.allMatches(this)) {
+        length += _addReplaceSlice(matches, startIndex, match.start);
+        matches.add(replacement);
+        length += replacementLength;
+        startIndex = match.end;
+      }
+    }
+    // No match, or a zero-length match at start with zero-length replacement.
+    if (startIndex == 0 && length == 0) return this;
+    length += _addReplaceSlice(matches, startIndex, this.length);
+    bool replacementIsOneByte = replacement._isOneByte;
+    if (replacementIsOneByte &&
+        length < _maxJoinReplaceOneByteStringLength &&
+        this._isOneByte) {
+      // TODO(lrn): Is there a cut-off point, or is runtime always faster?
+      return _joinReplaceAllOneByteResult(this, matches, length);
+    }
+    return _joinReplaceAllResult(this, matches, length, replacementIsOneByte);
+  }
+
+  /**
+   * As [_joinReplaceAllResult], but knowing that the result
+   * is always a [_OneByteString].
+   */
+  static String _joinReplaceAllOneByteResult(
+      String base, List matches, int length) {
+    _OneByteString result = _OneByteString._allocate(length);
+    int writeIndex = 0;
+    for (int i = 0; i < matches.length; i++) {
+      var entry = matches[i];
+      if (entry is _Smi) {
+        int sliceStart = entry;
+        int sliceEnd;
+        if (sliceStart < 0) {
+          int bits = -sliceStart;
+          int sliceLength = bits & _lengthMask;
+          sliceStart = bits >> _lengthBits;
+          sliceEnd = sliceStart + sliceLength;
+        } else {
+          i++;
+          // This function should only be called with valid matches lists.
+          // If the list is short, or sliceEnd is not an integer, one of
+          // the next few lines will throw anyway.
+          assert(i < matches.length);
+          sliceEnd = matches[i];
+        }
+        for (int j = sliceStart; j < sliceEnd; j++) {
+          result._setAt(writeIndex++, base.codeUnitAt(j));
+        }
+      } else {
+        // Replacement is a one-byte string.
+        String replacement = entry;
+        for (int j = 0; j < replacement.length; j++) {
+          result._setAt(writeIndex++, replacement.codeUnitAt(j));
+        }
+      }
+    }
+    assert(writeIndex == length);
+    return result;
+  }
+
+  /**
+   * Combine the results of a [replaceAll] match into a new string.
+   *
+   * The [matches] lists contains Smi index pairs representing slices of
+   * [base] and [String]s to be put in between the slices.
+   *
+   * The total [length] of the resulting string is known, as is
+   * whether the replacement strings are one-byte strings.
+   * If they are, then we have to check the base string slices to know
+   * whether the result must be a one-byte string.
+   */
+
+  external static String _joinReplaceAllResult(
+      String base, List matches, int length, bool replacementStringsAreOneByte);
+
+  String replaceAllMapped(Pattern pattern, String replace(Match match)) {
+    List matches = [];
+    int length = 0;
+    int startIndex = 0;
+    bool replacementStringsAreOneByte = true;
+    for (Match match in pattern.allMatches(this)) {
+      length += _addReplaceSlice(matches, startIndex, match.start);
+      var replacement = "${replace(match)}";
+      matches.add(replacement);
+      length += replacement.length;
+      replacementStringsAreOneByte =
+          replacementStringsAreOneByte && replacement._isOneByte;
+      startIndex = match.end;
+    }
+    if (matches.isEmpty) return this;
+    length += _addReplaceSlice(matches, startIndex, this.length);
+    if (replacementStringsAreOneByte &&
+        length < _maxJoinReplaceOneByteStringLength &&
+        this._isOneByte) {
+      return _joinReplaceAllOneByteResult(this, matches, length);
+    }
+    return _joinReplaceAllResult(
+        this, matches, length, replacementStringsAreOneByte);
+  }
+
+  String replaceFirstMapped(Pattern pattern, String replace(Match match),
+      [int startIndex = 0]) {
+    RangeError.checkValueInInterval(startIndex, 0, this.length, "startIndex");
+
+    var matches = pattern.allMatches(this, startIndex).iterator;
+    if (!matches.moveNext()) return this;
+    var match = matches.current;
+    var replacement = "${replace(match)}";
+    return replaceRange(match.start, match.end, replacement);
+  }
+
+  static String _matchString(Match match) => match[0]!;
+  static String _stringIdentity(String string) => string;
+
+  String _splitMapJoinEmptyString(
+      String onMatch(Match match), String onNonMatch(String nonMatch)) {
+    // Pattern is the empty string.
+    StringBuffer buffer = new StringBuffer();
+    int length = this.length;
+    int i = 0;
+    buffer.write(onNonMatch(""));
+    while (i < length) {
+      buffer.write(onMatch(new _StringMatch(i, this, "")));
+      // Special case to avoid splitting a surrogate pair.
+      int code = this.codeUnitAt(i);
+      if ((code & ~0x3FF) == 0xD800 && length > i + 1) {
+        // Leading surrogate;
+        code = this.codeUnitAt(i + 1);
+        if ((code & ~0x3FF) == 0xDC00) {
+          // Matching trailing surrogate.
+          buffer.write(onNonMatch(this.substring(i, i + 2)));
+          i += 2;
+          continue;
+        }
+      }
+      buffer.write(onNonMatch(this[i]));
+      i++;
+    }
+    buffer.write(onMatch(new _StringMatch(i, this, "")));
+    buffer.write(onNonMatch(""));
+    return buffer.toString();
+  }
+
+  String splitMapJoin(Pattern pattern,
+      {String onMatch(Match match)?, String onNonMatch(String nonMatch)?}) {
+    onMatch ??= _matchString;
+    onNonMatch ??= _stringIdentity;
+    if (pattern is String) {
+      String stringPattern = pattern;
+      if (stringPattern.isEmpty) {
+        return _splitMapJoinEmptyString(onMatch, onNonMatch);
+      }
+    }
+    StringBuffer buffer = new StringBuffer();
+    int startIndex = 0;
+    for (Match match in pattern.allMatches(this)) {
+      buffer.write(onNonMatch(this.substring(startIndex, match.start)));
+      buffer.write(onMatch(match).toString());
+      startIndex = match.end;
+    }
+    buffer.write(onNonMatch(this.substring(startIndex)));
+    return buffer.toString();
+  }
+
+  /**
+   * Convert all objects in [values] to strings and concat them
+   * into a result string.
+   * Modifies the input list if it contains non-`String` values.
+   */
+  @pragma("wasm:entry-point", "call")
+  static String _interpolate(final List values) {
+    final numValues = values.length;
+    int totalLength = 0;
+    int i = 0;
+    while (i < numValues) {
+      final e = values[i];
+      final s = e.toString();
+      values[i] = s;
+      if (s is _OneByteString) {
+        totalLength += s.length;
+        i++;
+      } else {
+        // Handle remaining elements without checking for one-byte-ness.
+        while (++i < numValues) {
+          final e = values[i];
+          values[i] = e.toString();
+        }
+        return _concatRangeNative(values, 0, numValues);
+      }
+    }
+    // All strings were one-byte strings.
+    return _OneByteString._concatAll(values, totalLength);
+  }
+
+  static ArgumentError _interpolationError(Object? o, Object? result) {
+    // Since Dart 2.0, [result] can only be null.
+    return new ArgumentError.value(
+        o, "object", "toString method returned 'null'");
+  }
+
+  Iterable<Match> allMatches(String string, [int start = 0]) {
+    if (start < 0 || start > string.length) {
+      throw new RangeError.range(start, 0, string.length, "start");
+    }
+    return new _StringAllMatchesIterable(string, this, start);
+  }
+
+  Match? matchAsPrefix(String string, [int start = 0]) {
+    if (start < 0 || start > string.length) {
+      throw new RangeError.range(start, 0, string.length);
+    }
+    if (start + this.length > string.length) return null;
+    for (int i = 0; i < this.length; i++) {
+      if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
+        return null;
+      }
+    }
+    return new _StringMatch(start, string, this);
+  }
+
+  List<String> split(Pattern pattern) {
+    if ((pattern is String) && pattern.isEmpty) {
+      List<String> result =
+          new List<String>.generate(this.length, (int i) => this[i]);
+      return result;
+    }
+    int length = this.length;
+    Iterator iterator = pattern.allMatches(this).iterator;
+    if (length == 0 && iterator.moveNext()) {
+      // A matched empty string input returns the empty list.
+      return <String>[];
+    }
+    List<String> result = <String>[];
+    int startIndex = 0;
+    int previousIndex = 0;
+    // 'pattern' may not be implemented correctly and therefore we cannot
+    // call _substringUnhchecked unless it is a trustworthy type (e.g. String).
+    while (true) {
+      if (startIndex == length || !iterator.moveNext()) {
+        result.add(this.substring(previousIndex, length));
+        break;
+      }
+      Match match = iterator.current;
+      if (match.start == length) {
+        result.add(this.substring(previousIndex, length));
+        break;
+      }
+      int endIndex = match.end;
+      if (startIndex == endIndex && endIndex == previousIndex) {
+        ++startIndex; // empty match, advance and restart
+        continue;
+      }
+      result.add(this.substring(previousIndex, match.start));
+      startIndex = previousIndex = endIndex;
+    }
+    return result;
+  }
+
+  List<int> get codeUnits => new CodeUnits(this);
+
+  Runes get runes => new Runes(this);
+
+  external String toUpperCase();
+
+  external String toLowerCase();
+
+  // Concatenate ['start', 'end'[ elements of 'strings'.
+  static String _concatRange(List<String> strings, int start, int end) {
+    if ((end - start) == 1) {
+      return strings[start];
+    }
+    return _concatRangeNative(strings, start, end);
+  }
+
+  // Call this method if all elements of [strings] are known to be strings
+  // but not all are known to be OneByteString(s).
+  static String _concatRangeNative(List strings, int start, int end) {
+    int totalLength = 0;
+    for (int i = start; i < end; i++) {
+      totalLength += unsafeCast<_StringBase>(strings[i]).length;
+    }
+    _TwoByteString result = _TwoByteString._allocate(totalLength);
+    int offset = 0;
+    for (int i = start; i < end; i++) {
+      _StringBase s = unsafeCast<_StringBase>(strings[i]);
+      offset = s._copyIntoTwoByteString(result, offset);
+    }
+    return result;
+  }
+
+  int _copyIntoTwoByteString(_TwoByteString result, int offset);
+
+  static int _combineHashes(int hash, int other_hash) {
+    hash += other_hash;
+    hash += hash << 10;
+    hash ^= (hash & 0xFFFFFFFF) >>> 6;
+    return hash;
+  }
+
+  static int _finalizeHash(int hash) {
+    hash += hash << 3;
+    hash ^= (hash & 0xFFFFFFFF) >>> 11;
+    hash += hash << 15;
+    hash &= 0x3FFFFFFF;
+    return hash == 0 ? 1 : hash;
+  }
+}
+
+@pragma("wasm:entry-point")
+class _OneByteString extends _StringBase {
+  @pragma("wasm:entry-point")
+  WasmIntArray<WasmI8> _array;
+
+  _OneByteString._withLength(int length)
+      : _array = WasmIntArray<WasmI8>(length),
+        super._();
+
+  // Same hash as VM
+  int _computeHashCode() {
+    WasmIntArray<WasmI8> array = _array;
+    int length = array.length;
+    int hash = 0;
+    for (int i = 0; i < length; i++) {
+      hash = _StringBase._combineHashes(hash, array.readUnsigned(i));
+    }
+    return _StringBase._finalizeHash(hash);
+  }
+
+  int codeUnitAt(int index) => _array.readUnsigned(index);
+
+  int get length => _array.length;
+
+  bool _isWhitespace(int codeUnit) {
+    return _StringBase._isOneByteWhitespace(codeUnit);
+  }
+
+  bool operator ==(Object other) {
+    return super == other;
+  }
+
+  String _substringUncheckedNative(int startIndex, int endIndex) {
+    int length = endIndex - startIndex;
+    var result = _OneByteString._withLength(length);
+    for (int i = 0; i < length; i++) {
+      result._setAt(i, codeUnitAt(startIndex + i));
+    }
+    return result;
+  }
+
+  List<String> _splitWithCharCode(int charCode) {
+    final parts = <String>[];
+    int i = 0;
+    int start = 0;
+    for (i = 0; i < this.length; ++i) {
+      if (this.codeUnitAt(i) == charCode) {
+        parts.add(this._substringUnchecked(start, i));
+        start = i + 1;
+      }
+    }
+    parts.add(this._substringUnchecked(start, i));
+    return parts;
+  }
+
+  List<String> split(Pattern pattern) {
+    if (pattern is _OneByteString && pattern.length == 1) {
+      return _splitWithCharCode(pattern.codeUnitAt(0));
+    }
+    return super.split(pattern);
+  }
+
+  // All element of 'strings' must be OneByteStrings.
+  static _concatAll(List strings, int totalLength) {
+    final result = _OneByteString._allocate(totalLength);
+    final to = result._array;
+    final stringsLength = strings.length;
+    int j = 0;
+    for (int s = 0; s < stringsLength; s++) {
+      final _OneByteString e = unsafeCast<_OneByteString>(strings[s]);
+      final from = e._array;
+      final length = from.length;
+      for (int i = 0; i < length; i++) {
+        to.write(j++, from.readUnsigned(i));
+      }
+    }
+    return result;
+  }
+
+  int _copyIntoTwoByteString(_TwoByteString result, int offset) {
+    final from = _array;
+    final int length = from.length;
+    final to = result._array;
+    int j = offset;
+    for (int i = 0; i < length; i++) {
+      to.write(j++, from.readUnsigned(i));
+    }
+    return j;
+  }
+
+  int indexOf(Pattern pattern, [int start = 0]) {
+    final len = this.length;
+    // Specialize for single character pattern.
+    if (pattern is String && pattern.length == 1 && start >= 0 && start < len) {
+      final patternCu0 = pattern.codeUnitAt(0);
+      if (patternCu0 > 0xFF) {
+        return -1;
+      }
+      for (int i = start; i < len; i++) {
+        if (this.codeUnitAt(i) == patternCu0) {
+          return i;
+        }
+      }
+      return -1;
+    }
+    return super.indexOf(pattern, start);
+  }
+
+  bool contains(Pattern pattern, [int start = 0]) {
+    final len = this.length;
+    if (pattern is String && pattern.length == 1 && start >= 0 && start < len) {
+      final patternCu0 = pattern.codeUnitAt(0);
+      if (patternCu0 > 0xFF) {
+        return false;
+      }
+      for (int i = start; i < len; i++) {
+        if (this.codeUnitAt(i) == patternCu0) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return super.contains(pattern, start);
+  }
+
+  String operator *(int times) {
+    if (times <= 0) return "";
+    if (times == 1) return this;
+    int length = this.length;
+    if (this.isEmpty) return this; // Don't clone empty string.
+    _OneByteString result = _OneByteString._allocate(length * times);
+    int index = 0;
+    for (int i = 0; i < times; i++) {
+      for (int j = 0; j < length; j++) {
+        result._setAt(index++, this.codeUnitAt(j));
+      }
+    }
+    return result;
+  }
+
+  String padLeft(int width, [String padding = ' ']) {
+    if (!padding._isOneByte) {
+      return super.padLeft(width, padding);
+    }
+    int length = this.length;
+    int delta = width - length;
+    if (delta <= 0) return this;
+    int padLength = padding.length;
+    int resultLength = padLength * delta + length;
+    _OneByteString result = _OneByteString._allocate(resultLength);
+    int index = 0;
+    if (padLength == 1) {
+      int padChar = padding.codeUnitAt(0);
+      for (int i = 0; i < delta; i++) {
+        result._setAt(index++, padChar);
+      }
+    } else {
+      for (int i = 0; i < delta; i++) {
+        for (int j = 0; j < padLength; j++) {
+          result._setAt(index++, padding.codeUnitAt(j));
+        }
+      }
+    }
+    for (int i = 0; i < length; i++) {
+      result._setAt(index++, this.codeUnitAt(i));
+    }
+    return result;
+  }
+
+  String padRight(int width, [String padding = ' ']) {
+    if (!padding._isOneByte) {
+      return super.padRight(width, padding);
+    }
+    int length = this.length;
+    int delta = width - length;
+    if (delta <= 0) return this;
+    int padLength = padding.length;
+    int resultLength = length + padLength * delta;
+    _OneByteString result = _OneByteString._allocate(resultLength);
+    int index = 0;
+    for (int i = 0; i < length; i++) {
+      result._setAt(index++, this.codeUnitAt(i));
+    }
+    if (padLength == 1) {
+      int padChar = padding.codeUnitAt(0);
+      for (int i = 0; i < delta; i++) {
+        result._setAt(index++, padChar);
+      }
+    } else {
+      for (int i = 0; i < delta; i++) {
+        for (int j = 0; j < padLength; j++) {
+          result._setAt(index++, padding.codeUnitAt(j));
+        }
+      }
+    }
+    return result;
+  }
+
+  // Lower-case conversion table for Latin-1 as string.
+  // Upper-case ranges: 0x41-0x5a ('A' - 'Z'), 0xc0-0xd6, 0xd8-0xde.
+  // Conversion to lower case performed by adding 0x20.
+  static const _LC_TABLE =
+      "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+      "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+      "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+      "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+      "\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+      "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x5b\x5c\x5d\x5e\x5f"
+      "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+      "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+      "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+      "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+      "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+      "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+      "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+      "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xd7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xdf"
+      "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+      "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+
+  // Upper-case conversion table for Latin-1 as string.
+  // Lower-case ranges: 0x61-0x7a ('a' - 'z'), 0xe0-0xff.
+  // The characters 0xb5 (µ) and 0xff (ÿ) have upper case variants
+  // that are not Latin-1. These are both marked as 0x00 in the table.
+  // The German "sharp s" \xdf (ß) should be converted into two characters (SS),
+  // and is also marked with 0x00.
+  // Conversion to lower case performed by subtracting 0x20.
+  static const _UC_TABLE =
+      "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+      "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+      "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+      "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+      "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+      "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+      "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+      "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f"
+      "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+      "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+      "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+      "\xb0\xb1\xb2\xb3\xb4\x00\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+      "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+      "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\x00"
+      "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+      "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xf7\xd8\xd9\xda\xdb\xdc\xdd\xde\x00";
+
+  String toLowerCase() {
+    for (int i = 0; i < this.length; i++) {
+      final c = this.codeUnitAt(i);
+      if (c == _LC_TABLE.codeUnitAt(c)) continue;
+      // Upper-case character found.
+      final result = _allocate(this.length);
+      for (int j = 0; j < i; j++) {
+        result._setAt(j, this.codeUnitAt(j));
+      }
+      for (int j = i; j < this.length; j++) {
+        result._setAt(j, _LC_TABLE.codeUnitAt(this.codeUnitAt(j)));
+      }
+      return result;
+    }
+    return this;
+  }
+
+  String toUpperCase() {
+    for (int i = 0; i < this.length; i++) {
+      final c = this.codeUnitAt(i);
+      // Continue loop if character is unchanged by upper-case conversion.
+      if (c == _UC_TABLE.codeUnitAt(c)) continue;
+
+      // Check rest of string for characters that do not convert to
+      // single-characters in the Latin-1 range.
+      for (int j = i; j < this.length; j++) {
+        final c = this.codeUnitAt(j);
+        if ((_UC_TABLE.codeUnitAt(c) == 0x00) && (c != 0x00)) {
+          // We use the 0x00 value for characters other than the null character,
+          // that don't convert to a single Latin-1 character when upper-cased.
+          // In that case, call the generic super-class method.
+          return super.toUpperCase();
+        }
+      }
+      // Some lower-case characters found, but all upper-case to single Latin-1
+      // characters.
+      final result = _allocate(this.length);
+      for (int j = 0; j < i; j++) {
+        result._setAt(j, this.codeUnitAt(j));
+      }
+      for (int j = i; j < this.length; j++) {
+        result._setAt(j, _UC_TABLE.codeUnitAt(this.codeUnitAt(j)));
+      }
+      return result;
+    }
+    return this;
+  }
+
+  // Allocates a string of given length, expecting its content to be
+  // set using _setAt.
+
+  static _OneByteString _allocate(int length) {
+    return unsafeCast<_OneByteString>(allocateOneByteString(length));
+  }
+
+  external static _OneByteString _allocateFromOneByteList(
+      List<int> list, int start, int end);
+
+  // This is internal helper method. Code point value must be a valid
+  // Latin1 value (0..0xFF), index must be valid.
+
+  void _setAt(int index, int codePoint) {
+    writeIntoOneByteString(this, index, codePoint);
+  }
+
+  // Should be optimizable to a memory move.
+  // Accepts both _OneByteString and _ExternalOneByteString as argument.
+  // Returns index after last character written.
+  int _setRange(int index, String oneByteString, int start, int end) {
+    assert(oneByteString._isOneByte);
+    assert(0 <= start);
+    assert(start <= end);
+    assert(end <= oneByteString.length);
+    assert(0 <= index);
+    assert(index + (end - start) <= length);
+    for (int i = start; i < end; i++) {
+      _setAt(index, oneByteString.codeUnitAt(i));
+      index += 1;
+    }
+    return index;
+  }
+}
+
+@pragma("wasm:entry-point")
+class _TwoByteString extends _StringBase {
+  @pragma("wasm:entry-point")
+  WasmIntArray<WasmI16> _array;
+
+  _TwoByteString._withLength(int length)
+      : _array = WasmIntArray<WasmI16>(length),
+        super._();
+
+  // Same hash as VM
+  int _computeHashCode() {
+    WasmIntArray<WasmI16> array = _array;
+    int length = array.length;
+    int hash = 0;
+    for (int i = 0; i < length; i++) {
+      hash = _StringBase._combineHashes(hash, array.readUnsigned(i));
+    }
+    return _StringBase._finalizeHash(hash);
+  }
+
+  // Allocates a string of given length, expecting its content to be
+  // set using _setAt.
+
+  static _TwoByteString _allocate(int length) {
+    return unsafeCast<_TwoByteString>(allocateTwoByteString(length));
+  }
+
+  static String _allocateFromTwoByteList(List<int> list, int start, int end) {
+    final int length = end - start;
+    final s = _allocate(length);
+    final array = s._array;
+    for (int i = 0; i < length; i++) {
+      array.write(i, list[start + i]);
+    }
+    return s;
+  }
+
+  // This is internal helper method. Code point value must be a valid
+  // UTF-16 value (0..0xFFFF), index must be valid.
+
+  void _setAt(int index, int codePoint) {
+    writeIntoTwoByteString(this, index, codePoint);
+  }
+
+  bool _isWhitespace(int codeUnit) {
+    return _StringBase._isTwoByteWhitespace(codeUnit);
+  }
+
+  int codeUnitAt(int index) => _array.readUnsigned(index);
+
+  int get length => _array.length;
+
+  bool operator ==(Object other) {
+    return super == other;
+  }
+
+  int _copyIntoTwoByteString(_TwoByteString result, int offset) {
+    final from = _array;
+    final int length = from.length;
+    final to = result._array;
+    int j = offset;
+    for (int i = 0; i < length; i++) {
+      to.write(j++, from.readUnsigned(i));
+    }
+    return j;
+  }
+}
+
+class _StringMatch implements Match {
+  const _StringMatch(this.start, this.input, this.pattern);
+
+  int get end => start + pattern.length;
+  String operator [](int g) => group(g);
+  int get groupCount => 0;
+
+  String group(int group) {
+    if (group != 0) {
+      throw new RangeError.value(group);
+    }
+    return pattern;
+  }
+
+  List<String> groups(List<int> groups) {
+    List<String> result = <String>[];
+    for (int g in groups) {
+      result.add(group(g));
+    }
+    return result;
+  }
+
+  final int start;
+  final String input;
+  final String pattern;
+}
+
+class _StringAllMatchesIterable extends Iterable<Match> {
+  final String _input;
+  final String _pattern;
+  final int _index;
+
+  _StringAllMatchesIterable(this._input, this._pattern, this._index);
+
+  Iterator<Match> get iterator =>
+      new _StringAllMatchesIterator(_input, _pattern, _index);
+
+  Match get first {
+    int index = _input.indexOf(_pattern, _index);
+    if (index >= 0) {
+      return new _StringMatch(index, _input, _pattern);
+    }
+    throw IterableElementError.noElement();
+  }
+}
+
+class _StringAllMatchesIterator implements Iterator<Match> {
+  final String _input;
+  final String _pattern;
+  int _index;
+  Match? _current;
+
+  _StringAllMatchesIterator(this._input, this._pattern, this._index);
+
+  bool moveNext() {
+    if (_index + _pattern.length > _input.length) {
+      _current = null;
+      return false;
+    }
+    var index = _input.indexOf(_pattern, _index);
+    if (index < 0) {
+      _index = _input.length + 1;
+      _current = null;
+      return false;
+    }
+    int end = index + _pattern.length;
+    _current = new _StringMatch(index, _input, _pattern);
+    // Empty match, don't start at same location again.
+    if (end == _index) end++;
+    _index = end;
+    return true;
+  }
+
+  Match get current => _current as Match;
+}
diff --git a/sdk/lib/_internal/wasm/lib/timer_patch.dart b/sdk/lib/_internal/wasm/lib/timer_patch.dart
new file mode 100644
index 0000000..47c7f03
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/timer_patch.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2022, 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.
+
+// part of "async_patch.dart";
+
+// Implementation of `Timer` and `scheduleMicrotask` via the JS event loop.
+
+import 'dart:_internal' show patch, scheduleCallback;
+
+@patch
+class Timer {
+  @patch
+  static Timer _createTimer(Duration duration, void callback()) {
+    return _OneShotTimer(duration, callback);
+  }
+
+  @patch
+  static Timer _createPeriodicTimer(
+      Duration duration, void callback(Timer timer)) {
+    return _PeriodicTimer(duration, callback);
+  }
+}
+
+abstract class _Timer implements Timer {
+  final double milliseconds;
+  bool isActive;
+  int tick;
+
+  _Timer(Duration duration)
+      : milliseconds = duration.inMilliseconds.toDouble(),
+        isActive = true,
+        tick = 0 {
+    _schedule();
+  }
+
+  void _schedule() {
+    scheduleCallback(milliseconds, () {
+      if (isActive) {
+        tick++;
+        _run();
+      }
+    });
+  }
+
+  void _run();
+
+  @override
+  void cancel() {
+    isActive = false;
+  }
+}
+
+class _OneShotTimer extends _Timer {
+  final void Function() callback;
+
+  _OneShotTimer(Duration duration, this.callback) : super(duration);
+
+  void _run() {
+    isActive = false;
+    callback();
+  }
+}
+
+class _PeriodicTimer extends _Timer {
+  final void Function(Timer) callback;
+
+  _PeriodicTimer(Duration duration, this.callback) : super(duration);
+
+  void _run() {
+    _schedule();
+    callback(this);
+  }
+}
+
+@patch
+class _AsyncRun {
+  @patch
+  static void _scheduleImmediate(void callback()) {
+    scheduleCallback(0, callback);
+  }
+}
diff --git a/sdk/lib/_internal/wasm/lib/type.dart b/sdk/lib/_internal/wasm/lib/type.dart
new file mode 100644
index 0000000..6db370d
--- /dev/null
+++ b/sdk/lib/_internal/wasm/lib/type.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, 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.
+
+// Representation of runtime types. Can only represent interface types so far,
+// and does not capture nullability.
+
+@pragma("wasm:entry-point")
+class _Type implements Type {
+  final int classId;
+  final List<_Type> typeArguments;
+
+  @pragma("wasm:entry-point")
+  const _Type(this.classId, [this.typeArguments = const []]);
+
+  bool operator ==(Object other) {
+    if (other is! _Type) return false;
+    if (classId != other.classId) return false;
+    for (int i = 0; i < typeArguments.length; i++) {
+      if (typeArguments[i] != other.typeArguments[i]) return false;
+    }
+    return true;
+  }
+
+  int get hashCode {
+    int hash = mix64(classId);
+    for (int i = 0; i < typeArguments.length; i++) {
+      hash = mix64(hash ^ typeArguments[i].hashCode);
+    }
+    return hash;
+  }
+
+  String toString() {
+    StringBuffer s = StringBuffer();
+    s.write("Type");
+    s.write(classId);
+    if (typeArguments.isNotEmpty) {
+      s.write("<");
+      for (int i = 0; i < typeArguments.length; i++) {
+        if (i > 0) s.write(",");
+        s.write(typeArguments[i]);
+      }
+      s.write(">");
+    }
+    return s.toString();
+  }
+}
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 8573ca4..12aee71 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -154,6 +154,81 @@
       }
     }
   },
+  "wasm": {
+    "libraries": {
+      "_internal": {
+        "uri": "internal/internal.dart",
+        "patches": [
+          "_internal/wasm/lib/internal_patch.dart",
+          "_internal/wasm/lib/class_id.dart",
+          "_internal/wasm/lib/patch.dart",
+          "_internal/wasm/lib/print_patch.dart",
+          "_internal/vm/lib/symbol_patch.dart"
+        ]
+      },
+      "async": {
+        "uri": "async/async.dart",
+        "patches": "_internal/wasm/lib/timer_patch.dart"
+      },
+      "collection": {
+        "uri": "collection/collection.dart",
+        "patches": [
+          "_internal/vm/lib/collection_patch.dart",
+          "_internal/vm/lib/compact_hash.dart",
+          "_internal/wasm/lib/hash_factories.dart"
+        ]
+      },
+      "convert": {
+        "uri": "convert/convert.dart",
+        "patches": "_internal/vm/lib/convert_patch.dart"
+      },
+      "core": {
+        "uri": "core/core.dart",
+        "patches": [
+          "_internal/wasm/lib/core_patch.dart",
+          "_internal/vm/lib/array_patch.dart",
+          "_internal/wasm/lib/bool.dart",
+          "_internal/vm/lib/bool_patch.dart",
+          "_internal/wasm/lib/date_patch.dart",
+          "_internal/wasm/lib/double.dart",
+          "_internal/wasm/lib/expando_patch.dart",
+          "_internal/wasm/lib/function.dart",
+          "_internal/wasm/lib/growable_list.dart",
+          "_internal/wasm/lib/identical_patch.dart",
+          "_internal/wasm/lib/immutable_map.dart",
+          "_internal/wasm/lib/int.dart",
+          "_internal/vm/lib/integers_patch.dart",
+          "_internal/wasm/lib/list.dart",
+          "_internal/vm/lib/null_patch.dart",
+          "_internal/vm/lib/map_patch.dart",
+          "_internal/wasm/lib/object_patch.dart",
+          "_internal/wasm/lib/string_buffer_patch.dart",
+          "_internal/wasm/lib/string_patch.dart",
+          "_internal/wasm/lib/type.dart"
+        ]
+      },
+      "developer": {
+        "uri": "developer/developer.dart",
+        "patches": [
+          "_internal/wasm/lib/developer.dart"
+        ]
+      },
+      "isolate": {
+        "uri": "isolate/isolate.dart"
+      },
+      "math": {
+        "uri": "math/math.dart",
+        "patches": "_internal/wasm/lib/math_patch.dart"
+      },
+      "typed_data": {
+        "uri": "typed_data/typed_data.dart",
+        "patches": "_internal/vm/lib/typed_data_patch.dart"
+      },
+      "wasm": {
+        "uri": "wasm/wasm_types.dart"
+      }
+    }
+  },
   "dart2js": {
     "include": [
       {
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index dcf81c0..a67349c 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -152,6 +152,66 @@
     vmservice_io:
       uri: "_internal/vm/bin/vmservice_io.dart"
 
+wasm:
+  libraries:
+    _internal:
+      uri: internal/internal.dart
+      patches:
+      - _internal/wasm/lib/internal_patch.dart
+      - _internal/wasm/lib/class_id.dart
+      - _internal/wasm/lib/patch.dart
+      - _internal/wasm/lib/print_patch.dart
+      - _internal/vm/lib/symbol_patch.dart
+    async:
+      uri: async/async.dart
+      patches: _internal/wasm/lib/timer_patch.dart
+    collection:
+      uri: collection/collection.dart
+      patches:
+      - _internal/vm/lib/collection_patch.dart
+      - _internal/vm/lib/compact_hash.dart
+      - _internal/wasm/lib/hash_factories.dart
+    convert:
+      uri: convert/convert.dart
+      patches: _internal/vm/lib/convert_patch.dart
+    core:
+      uri: core/core.dart
+      patches:
+      - _internal/wasm/lib/core_patch.dart
+      - _internal/vm/lib/array_patch.dart
+      - _internal/wasm/lib/bool.dart
+      - _internal/vm/lib/bool_patch.dart
+      - _internal/wasm/lib/date_patch.dart
+      - _internal/wasm/lib/double.dart
+      - _internal/wasm/lib/expando_patch.dart
+      - _internal/wasm/lib/function.dart
+      - _internal/wasm/lib/growable_list.dart
+      - _internal/wasm/lib/identical_patch.dart
+      - _internal/wasm/lib/immutable_map.dart
+      - _internal/wasm/lib/int.dart
+      - _internal/vm/lib/integers_patch.dart
+      - _internal/wasm/lib/list.dart
+      - _internal/vm/lib/null_patch.dart
+      - _internal/vm/lib/map_patch.dart
+      - _internal/wasm/lib/object_patch.dart
+      - _internal/wasm/lib/string_buffer_patch.dart
+      - _internal/wasm/lib/string_patch.dart
+      - _internal/wasm/lib/type.dart
+    developer:
+      uri: developer/developer.dart
+      patches:
+      - _internal/wasm/lib/developer.dart
+    isolate:
+      uri: isolate/isolate.dart
+    math:
+      uri: math/math.dart
+      patches: _internal/wasm/lib/math_patch.dart
+    typed_data:
+      uri: typed_data/typed_data.dart
+      patches: _internal/vm/lib/typed_data_patch.dart
+    wasm:
+      uri: wasm/wasm_types.dart
+
 dart2js:
   include:
     - target: "_dart2js_common"
diff --git a/sdk/lib/wasm/wasm_types.dart b/sdk/lib/wasm/wasm_types.dart
new file mode 100644
index 0000000..1ec7bb3
--- /dev/null
+++ b/sdk/lib/wasm/wasm_types.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2022, 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.
+
+library dart.wasm;
+
+// A collection a special Dart tytpes that are mapped directly to Wasm types
+// by the dart2wasm compiler. These types have a number of constraints:
+//
+// - They can only be used directly as types of local variables, fields, or
+//   parameter/return of static functions. No other uses of the types are valid.
+// - They are not assignable to or from any ordinary Dart types.
+// - The integer and float types can't be nullable.
+//
+// TODO(askesc): Give an error message if any of these constraints are violated.
+
+@pragma("wasm:entry-point")
+abstract class _WasmBase {}
+
+abstract class _WasmInt extends _WasmBase {}
+
+abstract class _WasmFloat extends _WasmBase {}
+
+/// The Wasm `anyref` type.
+@pragma("wasm:entry-point")
+class WasmAnyRef extends _WasmBase {}
+
+/// The Wasm `eqref` type.
+@pragma("wasm:entry-point")
+class WasmEqRef extends WasmAnyRef {}
+
+/// The Wasm `dataref` type.
+@pragma("wasm:entry-point")
+class WasmDataRef extends WasmEqRef {}
+
+abstract class _WasmArray extends WasmDataRef {
+  external int get length;
+}
+
+/// The Wasm `i8` storage type.
+@pragma("wasm:entry-point")
+class WasmI8 extends _WasmInt {}
+
+/// The Wasm `i16` storage type.
+@pragma("wasm:entry-point")
+class WasmI16 extends _WasmInt {}
+
+/// The Wasm `i32` type.
+@pragma("wasm:entry-point")
+class WasmI32 extends _WasmInt {}
+
+/// The Wasm `i64` type.
+@pragma("wasm:entry-point")
+class WasmI64 extends _WasmInt {}
+
+/// The Wasm `f32` type.
+@pragma("wasm:entry-point")
+class WasmF32 extends _WasmFloat {}
+
+/// The Wasm `f64` type.
+@pragma("wasm:entry-point")
+class WasmF64 extends _WasmFloat {}
+
+/// A Wasm array with integer element type.
+@pragma("wasm:entry-point")
+class WasmIntArray<T extends _WasmInt> extends _WasmArray {
+  external factory WasmIntArray(int length);
+
+  external int readSigned(int index);
+  external int readUnsigned(int index);
+  external void write(int index, int value);
+}
+
+/// A Wasm array with float element type.
+@pragma("wasm:entry-point")
+class WasmFloatArray<T extends _WasmFloat> extends _WasmArray {
+  external factory WasmFloatArray(int length);
+
+  external double read(int index);
+  external void write(int index, double value);
+}
+
+/// A Wasm array with reference element type, containing Dart objects.
+@pragma("wasm:entry-point")
+class WasmObjectArray<T extends Object?> extends _WasmArray {
+  external factory WasmObjectArray(int length);
+
+  external T read(int index);
+  external void write(int index, T value);
+}
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 277a778..75ebe8c 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -42,6 +42,7 @@
 LanguageFeatures/Abstract-external-fields/static_analysis_external_A05_t03: SkipByDesign # Non-JS-interop external members are not supported
 LanguageFeatures/Abstract-external-fields/syntax_A01_t03: SkipByDesign # Non-JS-interop external members are not supported
 LanguageFeatures/Abstract-external-fields/syntax_A02_t03: SkipByDesign # Non-JS-interop external members are not supported
+LanguageFeatures/FinalizationRegistry/ffi/*: SkipByDesign # dart:ffi is not supported
 LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecond_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
diff --git a/tests/co19/co19-dartdevc.status b/tests/co19/co19-dartdevc.status
index 3458c5c..94d2a50 100644
--- a/tests/co19/co19-dartdevc.status
+++ b/tests/co19/co19-dartdevc.status
@@ -39,6 +39,7 @@
 LanguageFeatures/Abstract-external-fields/static_analysis_external_A05_t03: SkipByDesign # External variables are not supported
 LanguageFeatures/Abstract-external-fields/syntax_A01_t03: SkipByDesign # External variables are not supported
 LanguageFeatures/Abstract-external-fields/syntax_A02_t03: SkipByDesign # External variables are not supported
+LanguageFeatures/FinalizationRegistry/ffi/*: SkipByDesign # dart:ffi is not supported
 LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecond_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
 LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: SkipByDesign # microseconds are not supported in JavaScript
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 4e3c7d4..3254ec0 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -27,10 +27,16 @@
 LibTest/core/List/List_class_A01_t02: Slow, Pass
 LibTest/core/List/List_class_A01_t03: Slow, Pass
 
+[ $runtime == dart_precompiled && $system == windows ]
+LanguageFeatures/FinalizationRegistry/ffi/*: SkipByDesign # https://dartbug.com/40579 Dart C API symbols not available.
+
 [ $runtime == dart_precompiled && ($arch == simarm64 || $arch == simarm64c || $arch == simriscv32 || $arch == simriscv64) ]
 LibTest/collection/ListBase/ListBase_class_A01_t01: SkipSlow # Issue 43036
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: SkipSlow # Issue 43036
 
+[ $arch == simarm || $arch == simarm64 ]
+LanguageFeatures/FinalizationRegistry/ffi/*: SkipByDesign # https://github.com/dart-lang/sdk/issues/37299
+
 # It makes no sense to run any test that uses spawnURI under the simulator
 # as that would involve running CFE (the front end) in simulator mode
 # to compile the URI file specified in spawnURI code.
diff --git a/tests/language/language_dart2wasm.status b/tests/language/language_dart2wasm.status
new file mode 100644
index 0000000..3dea313
--- /dev/null
+++ b/tests/language/language_dart2wasm.status
@@ -0,0 +1,10 @@
+# Copyright (c) 2022, 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.
+# Sections in this file should contain "$compiler == dart2wasm".
+
+[ $compiler == dart2wasm ]
+vm/*: SkipByDesign # Tests for the VM.
+
+[ $compiler == dart2wasm && $runtime == d8 ]
+import/conditional_string_test: SkipByDesign # No XHR in d8
diff --git a/tools/VERSION b/tools/VERSION
index 17b79a3..9cab9b0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 112
+PRERELEASE 113
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 37803b4..724d094 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -185,6 +185,41 @@
       "xcodebuild/ReleaseX64/dart2js_platform.dill",
       "xcodebuild/ReleaseX64/dart2js_platform_unsound.dill"
     ],
+    "dart2wasm_hostasserts": [
+      ".packages",
+      ".dart_tool/package_config.json",
+      "out/ReleaseX64/dart",
+      "out/ReleaseX64/dart2wasm_platform.dill",
+      "pkg/",
+      "runtime/tests/",
+      "samples-dev/",
+      "samples/",
+      "sdk/",
+      "tests/.dart_tool/package_config.json",
+      "tests/angular/",
+      "tests/co19/co19-analyzer.status",
+      "tests/co19/co19-co19.status",
+      "tests/co19/co19-dart2js.status",
+      "tests/co19/co19-dartdevc.status",
+      "tests/co19/co19-kernel.status",
+      "tests/co19/co19-runtime.status",
+      "tests/corelib/",
+      "tests/web/",
+      "tests/dartdevc/",
+      "tests/language/",
+      "tests/language_2/",
+      "tests/lib/",
+      "tests/light_unittest.dart",
+      "tests/search/",
+      "tests/ffi/",
+      "third_party/d8/",
+      "third_party/pkg/",
+      "third_party/pkg_tested/",
+      "third_party/requirejs/",
+      "tools/",
+      "xcodebuild/ReleaseX64/dart",
+      "xcodebuild/ReleaseX64/dart2wasm_platform.dill"
+    ],
     "front-end": [
       ".packages",
       ".dart_tool/package_config.json",
@@ -705,6 +740,13 @@
         "builder-tag": "dart2js-strong"
       }
     },
+    "dart2wasm-hostasserts-linux-x64-d8": {
+      "options": {
+        "host-checked": true,
+        "timeout": 240,
+        "builder-tag": "dart2wasm"
+      }
+    },
     "dartkp-android-(debug|product|release)-arm_x64": {
       "options": {
         "builder-tag": "crossword",
@@ -2888,6 +2930,33 @@
     },
     {
       "builders": [
+        "dart2wasm-linux-x64-d8"
+      ],
+      "meta": {
+        "description": "dart2wasm tests."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "create_sdk"
+          ]
+        },
+        {
+          "name": "dart2wasm d8 tests",
+          "arguments": [
+            "-ndart2wasm-hostasserts-linux-x64-d8",
+            "language",
+            "corelib"
+          ],
+          "shards": 6,
+          "fileset": "dart2wasm_hostasserts"
+        }
+      ]
+    },
+    {
+      "builders": [
         "dart-sdk-linux"
       ],
       "meta": {
