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/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/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/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/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": {
