Version 2.14.0-177.0.dev

Merge commit '93c96d58575f3346d93106435751393ab55af2b8' into 'dev'
diff --git a/DEPS b/DEPS
index ba07759..68a34a5 100644
--- a/DEPS
+++ b/DEPS
@@ -107,7 +107,7 @@
 
   "chromedriver_tag": "83.0.4103.39",
   "dartdoc_rev" : "305713608c25106d95f9114418d895e08d1a9e9c",
-  "devtools_rev" : "e138d55437a59838607415ef21f20bd6c4955dbc",
+  "devtools_rev" : "b3bf672474a2bff82f33e1176aa803539baa0d60+1",
   "jsshell_tag": "version:88.0",
   "ffi_rev": "f3346299c55669cc0db48afae85b8110088bf8da",
   "fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
index fb8cb1e..e8ba7bf 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_non_standard_sdk_test.dart
@@ -52,7 +52,7 @@
 ''');
 
     File(path.join(sdkPath, 'lib', 'fake', 'fake.dart')).writeAsStringSync(r'''
-class Fake {} 
+class Fake {}
 ''');
 
     var libsInternalDir = path.join(sdkPath, 'lib', '_internal');
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index 08367b2..1a7a8c2 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
@@ -335,7 +335,7 @@
     class MyClass {
       String aaa;
     }
-      
+
     /// before [bbb] after
     int double(int bbb) => bbb * 2;
     ''';
@@ -708,7 +708,7 @@
     final content = '''
     f({String a}) {
       f(a: a);
-    }    
+    }
     ''';
 
     final expected = [
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index ae69a11..bfaddb0 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -25,7 +25,7 @@
   Future<void> test_CONSTRUCTOR_required_parameters_1() async {
     writeTestPackageConfig(meta: true);
     await resolveTestCode('''
-import 'package:meta/meta.dart';    
+import 'package:meta/meta.dart';
 class A {
   const A.myConstructor(int a, {int b, @required int c});
 }''');
@@ -40,7 +40,7 @@
   Future<void> test_CONSTRUCTOR_required_parameters_2() async {
     writeTestPackageConfig(meta: true);
     await resolveTestCode('''
-import 'package:meta/meta.dart';    
+import 'package:meta/meta.dart';
 class A {
   const A.myConstructor(int a, {int b, @required int d, @required int c});
 }''');
@@ -57,7 +57,7 @@
     writeTestPackageConfig(meta: true);
     verifyNoTestUnitErrors = false;
     await resolveTestCode('''
-import 'package:meta/meta.dart';    
+import 'package:meta/meta.dart';
 class A {
   const A.myConstructor(int a, {int b, @required int d, @required int c, int a});
 }''');
@@ -138,7 +138,7 @@
   Future<void> test_CONSTRUCTOR_required_parameters_1() async {
     writeTestPackageConfig(meta: true);
     await resolveTestCode('''
-import 'package:meta/meta.dart';    
+import 'package:meta/meta.dart';
 class A {
   const A.myConstructor(int a, {int? b, required int c});
 }''');
@@ -153,7 +153,7 @@
   Future<void> test_CONSTRUCTOR_required_parameters_2() async {
     writeTestPackageConfig(meta: true);
     await resolveTestCode('''
-import 'package:meta/meta.dart';    
+import 'package:meta/meta.dart';
 class A {
   const A.myConstructor(int a, {int? b, required int d, required int c});
 }''');
@@ -170,7 +170,7 @@
     writeTestPackageConfig(meta: true);
     verifyNoTestUnitErrors = false;
     await resolveTestCode('''
-import 'package:meta/meta.dart';    
+import 'package:meta/meta.dart';
 class A {
   const A.myConstructor(int a, {int b, required int d, required int c, int a});
 }''');
diff --git a/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
index 12a2cad..5def996 100644
--- a/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/extension_member_contributor_test.dart
@@ -30,7 +30,7 @@
   int b = 0;
 }
 extension E on B {
-  void e() { 
+  void e() {
     ^
   }
 }
@@ -49,7 +49,7 @@
   set b(int b) { }
 }
 extension E on B {
-  void e() { 
+  void e() {
     ^
   }
 }
@@ -68,7 +68,7 @@
   void b() { }
 }
 extension E on B {
-  void e() { 
+  void e() {
     ^
   }
 }
@@ -85,7 +85,7 @@
 }
 
 extension E on A<int> {
-  void e() { 
+  void e() {
     ^
   }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 9214947..760fd21 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -373,7 +373,7 @@
   Future<void> test_ArgumentList_namedFieldParam_tear_off() async {
     addSource('/home/test/lib/a.dart', '''
 typedef void VoidCallback();
-        
+
 class Button {
   final VoidCallback onPressed;
   Button({this.onPressed});
@@ -387,8 +387,8 @@
   build() =>
     new Button(
       onPressed: ^
-    );  
-}    
+    );
+}
 ''');
     await computeSuggestions();
 
@@ -450,7 +450,7 @@
   Future<void> test_ArgumentList_namedParam_tear_off() async {
     addSource('/home/test/lib/a.dart', '''
 typedef void VoidCallback();
-        
+
 class Button {
   Button({VoidCallback onPressed});
 }
@@ -463,8 +463,8 @@
   build() =>
     new Button(
       onPressed: ^
-    );  
-}    
+    );
+}
 ''');
     await computeSuggestions();
 
@@ -478,7 +478,7 @@
   Future<void> test_ArgumentList_namedParam_tear_off_1() async {
     addSource('/home/test/lib/a.dart', '''
 typedef void VoidCallback();
-        
+
 class Button {
   Button({VoidCallback onPressed, int x});
 }
@@ -491,8 +491,8 @@
   build() =>
     new Button(
       onPressed: ^
-    );  
-}    
+    );
+}
 ''');
     await computeSuggestions();
 
@@ -506,7 +506,7 @@
   Future<void> test_ArgumentList_namedParam_tear_off_2() async {
     addSource('/home/test/lib/a.dart', '''
 typedef void VoidCallback();
-        
+
 class Button {
   Button({ int x, VoidCallback onPressed);
 }
@@ -519,8 +519,8 @@
   build() =>
     new Button(
       onPressed: ^
-    );  
-}    
+    );
+}
 ''');
     await computeSuggestions();
 
diff --git a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
index 6106c93..540729e 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
@@ -547,7 +547,7 @@
 
 class MyWidget extends StatelessWidget {
   final String foo;
-  
+
   MyWidget(this.foo);
 
   @override
@@ -577,7 +577,7 @@
 
 class MyWidget extends StatelessWidget {
   final String foo;
-  
+
   MyWidget(this.foo);
 
   @override
@@ -622,7 +622,7 @@
 
 class MyWidget extends StatelessWidget {
   final String field;
-  
+
   MyWidget(this.field);
 
   @override
@@ -638,7 +638,7 @@
 
 class MyWidget extends StatelessWidget {
   final String field;
-  
+
   MyWidget(this.field);
 
   @override
@@ -760,7 +760,7 @@
 
 class MyWidget extends StatelessWidget {
   String field;
-  
+
   MyWidget(this.field);
 
   @override
@@ -955,7 +955,7 @@
 
 class MyWidget extends StatelessWidget {
   final String _field;
-  
+
   MyWidget(this._field);
 
   @override
@@ -971,7 +971,7 @@
 
 class MyWidget extends StatelessWidget {
   final String _field;
-  
+
   MyWidget(this._field);
 
   @override
@@ -1003,7 +1003,7 @@
 class MyWidget extends StatelessWidget {
   final int field;
   final String _field;
-  
+
   MyWidget(this.field, this._field);
 
   @override
@@ -1020,7 +1020,7 @@
 class MyWidget extends StatelessWidget {
   final int field;
   final String _field;
-  
+
   MyWidget(this.field, this._field);
 
   @override
@@ -1053,7 +1053,7 @@
 
 class MyWidget extends StatelessWidget {
   final String field;
-  
+
   MyWidget(this.field);
 
   @override
@@ -1075,7 +1075,7 @@
 
 class MyWidget extends StatelessWidget {
   final String field;
-  
+
   MyWidget(this.field);
 
   @override
diff --git a/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
index b7e3770..32dfb0f 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_extension_member_test.dart
@@ -228,7 +228,7 @@
 main() {
   0.test;
   0.test = 2;
-  
+
   E(0).test;
   E(0).test = 3;
 }
@@ -251,7 +251,7 @@
 main() {
   0.newName;
   0.newName = 2;
-  
+
   E(0).newName;
   E(0).newName = 3;
 }
@@ -271,7 +271,7 @@
 main() {
   0.test;
   0.test = 2;
-  
+
   E(0).test;
   E(0).test = 3;
 }
@@ -294,7 +294,7 @@
 main() {
   0.newName;
   0.newName = 2;
-  
+
   E(0).newName;
   E(0).newName = 3;
 }
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index d4ed8df..62e7ad9 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -68,7 +68,7 @@
   @setterAnnotation1/*7:INC*/
   @setterAnnotation2/*7:EXC:ANNOTATIONS*/
   void set myThing(int value) {}
-  
+
   @methodAnnotation1/*8:INC*/
   @methodAnnotation2/*8:EXC:ANNOTATIONS*/
   void myMethod() {}
diff --git a/pkg/analysis_server/test/src/computer/outline_computer_test.dart b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
index da4b72a..6829836 100644
--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
@@ -1026,9 +1026,9 @@
     var unitOutline = await _computeOutline('''
 class A {
   int fieldA, fieldB = 2;
-  
+
   int fieldC;
-  
+
   /// Documentation.
   int fieldD;
 }
@@ -1071,10 +1071,10 @@
       expect(element.kind, ElementKind.FIELD);
       expect(element.name, 'fieldC');
 
-      expect(outline.offset, 41);
+      expect(outline.offset, 39);
       expect(outline.length, 11);
 
-      expect(outline.codeOffset, 45);
+      expect(outline.codeOffset, 43);
       expect(outline.codeLength, 6);
     }
 
@@ -1085,10 +1085,10 @@
       expect(element.kind, ElementKind.FIELD);
       expect(element.name, 'fieldD');
 
-      expect(outline.offset, 58);
+      expect(outline.offset, 54);
       expect(outline.length, 32);
 
-      expect(outline.codeOffset, 83);
+      expect(outline.codeOffset, 79);
       expect(outline.codeLength, 6);
     }
   }
@@ -1136,7 +1136,7 @@
     var unitOutline = await _computeOutline('''
 class A {
   int methodA() {}
-  
+
   /// Documentation.
   @override
   int methodB() {}
@@ -1166,10 +1166,10 @@
       expect(element.kind, ElementKind.METHOD);
       expect(element.name, 'methodB');
 
-      expect(outline.offset, 34);
+      expect(outline.offset, 32);
       expect(outline.length, 49);
 
-      expect(outline.codeOffset, 67);
+      expect(outline.codeOffset, 65);
       expect(outline.codeLength, 16);
     }
   }
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
index 1cd6ba2..f186301 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
@@ -449,7 +449,7 @@
 class WidgetA extends StatelessWidget {
   final Widget top;
   final Widget bottom;
-  
+
   WidgetA({this.top, this.bottom});
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart
index f13b966..c6a0061 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/shadow_field_test.dart
@@ -44,7 +44,7 @@
   num f = 0;
 
   void m() {
-    while (true) 
+    while (true)
       if (f is int) {
         print((f as int).abs());
       }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
index 2e96ea7..bf448d7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
@@ -103,7 +103,7 @@
 main() {
   if (1 == 1
 // start
-&& 2 
+&& 2
 // end
 == 2
 ) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart
index 5bcdd3e..33d2b33 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_into_expression_body_test.dart
@@ -27,7 +27,7 @@
   Future<void> test_async() async {
     await resolveTestCode('''
 class A {
-  mmm() async { 
+  mmm() async {
     return 42;
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
index fa9beb5..97efe0f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/diagnostics/invalid_value_one_of_test.dart
@@ -44,13 +44,13 @@
     - kind: 'addTypeParameter'
       index: 0
       name: 'T'
-      argumentValue: 
+      argumentValue:
         expression: ''
         variables:
           x:
             kind: 'invalid'
 ''', [
-      error(TransformSetErrorCode.invalidValueOneOf, 280, 9),
+      error(TransformSetErrorCode.invalidValueOneOf, 279, 9),
     ]);
   }
 }
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index 096db25..fbe690f 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -29,7 +29,7 @@
     writeln('''/**
  * The interface {@code AnalysisServer} defines the behavior of objects that interface to an
  * analysis server.
- * 
+ *
  * @coverage dart.server
  */''');
     makeClass('public interface AnalysisServer', () {
@@ -40,7 +40,7 @@
         writeln('''/**
  * Add the given listener to the list of listeners that will receive notification when new
  * analysis results become available.
- * 
+ *
  * @param listener the listener to be added
  */''');
         writeln(
@@ -54,7 +54,7 @@
         writeln('''/**
  * Remove the given listener from the list of listeners that will receive notification when new
    * analysis results become available.
- * 
+ *
  * @param listener the listener to be removed
  */''');
         writeln(
@@ -68,7 +68,7 @@
         writeln('''/**
  * Add the given listener to the list of listeners that will receive notification when
    * requests are made by an analysis server client.
- * 
+ *
  * @param listener the listener to be added
  */''');
         writeln('public void addRequestListener(RequestListener listener);');
@@ -81,7 +81,7 @@
         writeln('''/**
  * Remove the given listener from the list of listeners that will receive notification when
    * requests are made by an analysis server client.
- * 
+ *
  * @param listener the listener to be removed
  */''');
         writeln('public void removeRequestListener(RequestListener listener);');
@@ -94,7 +94,7 @@
         writeln('''/**
  * Add the given listener to the list of listeners that will receive notification when
  * responses are received by an analysis server client.
- * 
+ *
  * @param listener the listener to be added
  */''');
         writeln('public void addResponseListener(ResponseListener listener);');
@@ -107,7 +107,7 @@
         writeln('''/**
  * Remove the given listener from the list of listeners that will receive notification when
    * responses are received by an analysis server client.
- * 
+ *
  * @param listener the listener to be removed
  */''');
         writeln(
@@ -121,7 +121,7 @@
         writeln('''/**
  * Add the given listener to the list of listeners that will receive notification when the server
  * is not active
- * 
+ *
  * @param listener the listener to be added
  */''');
         writeln(
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index d0ec493..5d76afe 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -72,7 +72,8 @@
     }
   }
 
-  void _resolveVariable(VariableElement element) {
+  void _resolveVariable(PropertyInducingElement element) {
+    element as PropertyInducingElementImpl;
     if (element.isSynthetic) return;
 
     var variable = linker.getLinkingNode(element) as VariableDeclaration;
@@ -80,14 +81,22 @@
 
     var declarationList = variable.parent as VariableDeclarationList;
     var typeNode = declarationList.type;
-    if (typeNode != null) {
-      if (declarationList.isConst ||
-          declarationList.isFinal && _enclosingClassHasConstConstructor) {
-        var astResolver =
-            AstResolver(linker, _unitElement, _scope, variable.initializer!);
-        astResolver.resolveExpression(() => variable.initializer!,
-            contextType: typeNode.type);
-      }
+
+    DartType contextType;
+    if (element.hasTypeInferred) {
+      contextType = element.type;
+    } else if (typeNode != null) {
+      contextType = typeNode.typeOrThrow;
+    } else {
+      contextType = DynamicTypeImpl.instance;
+    }
+
+    if (declarationList.isConst ||
+        declarationList.isFinal && _enclosingClassHasConstConstructor) {
+      var astResolver =
+          AstResolver(linker, _unitElement, _scope, variable.initializer!);
+      astResolver.resolveExpression(() => variable.initializer!,
+          contextType: contextType);
     }
 
     if (element is ConstVariableElement) {
@@ -426,6 +435,10 @@
 
   @override
   List<_InferenceNode> computeDependencies() {
+    if (_elementImpl.hasTypeInferred) {
+      return const <_InferenceNode>[];
+    }
+
     _resolveInitializer(forDependencies: true);
 
     var collector = _InferenceDependenciesCollector();
@@ -440,14 +453,16 @@
 
   @override
   void evaluate() {
+    if (_elementImpl.hasTypeInferred) {
+      return;
+    }
+
     _resolveInitializer(forDependencies: false);
 
-    if (!_elementImpl.hasTypeInferred) {
-      var initializerType = _node.initializer!.typeOrThrow;
-      initializerType = _refineType(initializerType);
-      _elementImpl.type = initializerType;
-      _elementImpl.hasTypeInferred = true;
-    }
+    var initializerType = _node.initializer!.typeOrThrow;
+    initializerType = _refineType(initializerType);
+    _elementImpl.type = initializerType;
+    _elementImpl.hasTypeInferred = true;
 
     isEvaluated = true;
   }
@@ -455,6 +470,7 @@
   @override
   void markCircular(List<_InferenceNode> cycle) {
     _elementImpl.type = DynamicTypeImpl.instance;
+    _elementImpl.hasTypeInferred = true;
 
     var cycleNames = <String>{};
     for (var inferenceNode in cycle) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 236dd23..69ca0e1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1026,6 +1026,36 @@
 ''');
   }
 
+  test_class_field_inheritedContextType_double() async {
+    var library = await checkLibrary('''
+abstract class A {
+  const A();
+  double get foo;
+}
+class B extends A {
+  const B();
+  final foo = 2;
+}
+''');
+    checkElementText(
+        library,
+        r'''
+abstract class A {
+  double get foo;
+  const A();
+}
+class B extends A {
+  final double foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 2
+        staticType: double
+  const B();
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_class_field_static() async {
     var library = await checkLibrary('class C { static int i; }');
     checkElementText(library, r'''
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index ef103f2c..34a34f9 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -578,10 +578,34 @@
 
   @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    if (identical(entity, node.expression)) {
+    var expression = node.expression;
+    if (identical(entity, expression)) {
       optype.completionLocation = 'ExpressionFunctionBody_expression';
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
+      var parent = node.parent;
+      if (parent is FunctionExpression) {
+        var type = parent.staticType;
+        if (type is FunctionType) {
+          if (type.returnType.isVoid) {
+            // TODO(brianwilkerson) Determine whether the return type can ever
+            //  be inferred as void and remove this case if it can't be.
+            optype.includeVoidReturnSuggestions = true;
+          } else {
+            var grandparent = parent.parent;
+            if (grandparent is ArgumentList) {
+              var parameter = parent.staticParameterElement;
+              if (parameter != null) {
+                var parameterType = parameter.type;
+                if (parameterType is FunctionType &&
+                    parameterType.returnType.isVoid) {
+                  optype.includeVoidReturnSuggestions = true;
+                }
+              }
+            }
+          }
+        }
+      }
     }
   }
 
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index 66c0b73..3c8fe89 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -1012,7 +1012,24 @@
         completionLocation: 'ExpressionFunctionBody_expression',
         constructors: true,
         returnValue: true,
-        typeNames: true);
+        typeNames: true,
+        voidReturn: true);
+  }
+
+  Future<void> test_expressionFunctionBody_voidReturnType() async {
+    // SimpleIdentifier  ExpressionFunctionBody  FunctionExpression
+    addTestSource('''
+void f() {
+  g(() => ^);
+}
+void g(void Function() f) {}
+''');
+    await assertOpType(
+        completionLocation: 'ExpressionFunctionBody_expression',
+        constructors: true,
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true);
   }
 
   Future<void> test_expressionStatement_beginning() async {
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 74f994c..7e0a44d 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -52,6 +52,11 @@
 
   static const String experimentNewRti = '--experiment-new-rti';
 
+  /// Use the dart2js lowering of late instance variables rather than the CFE
+  /// lowering.
+  static const String experimentLateInstanceVariables =
+      '--experiment-late-instance-variables';
+
   static const String enableLanguageExperiments = '--enable-experiment';
 
   static const String fastStartup = '--fast-startup';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index e193c1c..43f80a5 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -602,6 +602,7 @@
     new OptionHandler(Flags.experimentUnreachableMethodsThrow, passThrough),
     new OptionHandler(Flags.experimentCallInstrumentation, passThrough),
     new OptionHandler(Flags.experimentNewRti, ignoreOption),
+    new OptionHandler(Flags.experimentLateInstanceVariables, passThrough),
     new OptionHandler('${Flags.mergeFragmentsThreshold}=.+', passThrough),
 
     // The following three options must come last.
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 01c06dd..ee3f962 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -17,6 +17,7 @@
 import 'package:kernel/target/changed_structure_notifier.dart';
 import 'package:kernel/target/targets.dart';
 
+import '../options.dart';
 import 'invocation_mirror_constants.dart';
 import 'transformations/lowering.dart' as lowering show transformLibraries;
 
@@ -77,17 +78,20 @@
   @override
   final String name;
 
-  final bool omitLateNames;
+  final CompilerOptions options;
 
   Map<String, ir.Class> _nativeClasses;
 
-  Dart2jsTarget(this.name, this.flags, {this.omitLateNames = false});
+  Dart2jsTarget(this.name, this.flags, {this.options});
 
   @override
   bool get enableNoSuchMethodForwarders => true;
 
   @override
-  final int enabledLateLowerings = _enabledLateLowerings;
+  int get enabledLateLowerings =>
+      (options != null && options.experimentLateInstanceVariables)
+          ? LateLowering.none
+          : _enabledLateLowerings;
 
   @override
   bool get supportsLateLoweringSentinel => true;
@@ -161,8 +165,7 @@
               _nativeClasses)
           .visitLibrary(library);
     }
-    lowering.transformLibraries(libraries, coreTypes, hierarchy,
-        omitLateNames: omitLateNames);
+    lowering.transformLibraries(libraries, coreTypes, hierarchy, options);
     logger?.call("Lowering transformations performed");
   }
 
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index a348813..5a83702 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -136,8 +136,8 @@
         }
       } else {
         bool verbose = false;
-        Target target = Dart2jsTarget(targetName, TargetFlags(),
-            omitLateNames: _options.omitLateNames);
+        Target target =
+            Dart2jsTarget(targetName, TargetFlags(), options: _options);
         fe.FileSystem fileSystem = CompilerFileSystem(_compilerInput);
         fe.Verbosity verbosity = _options.verbosity;
         fe.DiagnosticMessageHandler onDiagnostic =
diff --git a/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart b/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart
index 5b9b6e4..210bbcb 100644
--- a/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart
+++ b/pkg/compiler/lib/src/kernel/transformations/late_lowering.dart
@@ -6,16 +6,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/type_algebra.dart';
 
-bool _shouldLowerVariable(VariableDeclaration variable) => variable.isLate;
-
-bool _shouldLowerUninitializedVariable(VariableDeclaration variable) =>
-    _shouldLowerVariable(variable) && variable.initializer == null;
-
-bool _shouldLowerInitializedVariable(VariableDeclaration variable) =>
-    _shouldLowerVariable(variable) && variable.initializer != null;
-
-bool _shouldLowerField(Field field) =>
-    field.isLate && field.isStatic && field.initializer == null;
+import '../../options.dart';
 
 class _Reader {
   final Procedure _procedure;
@@ -30,7 +21,8 @@
 class LateLowering {
   final CoreTypes _coreTypes;
 
-  final bool omitLateNames;
+  final bool _omitLateNames;
+  final bool _lowerInstanceVariables;
 
   final _Reader _readLocal;
   final _Reader _readField;
@@ -38,15 +30,26 @@
   final _Reader _readInitializedFinal;
 
   // Each map contains the mapping from late local variables to cells for a
-  // given function scope.
+  // given function scope. All late local variables are lowered to cells.
   final List<Map<VariableDeclaration, VariableDeclaration>> _variableCells = [];
 
+  // Uninitialized late static fields are lowered to cells.
   final Map<Field, Field> _fieldCells = {};
 
+  // Late instance fields are lowered to a backing field (plus a getter/setter
+  // pair).
+  final Map<Field, Field> _backingInstanceFields = {};
+
+  // TODO(fishythefish): Remove this when [FieldInitializer] maintains a correct
+  // [Reference] to its [Field].
+  final Map<Procedure, Field> _getterToField = {};
+
   Member _contextMember;
 
-  LateLowering(this._coreTypes, {this.omitLateNames})
-      : assert(omitLateNames != null),
+  LateLowering(this._coreTypes, CompilerOptions _options)
+      : _omitLateNames = _options?.omitLateNames ?? false,
+        _lowerInstanceVariables =
+            _options?.experimentLateInstanceVariables ?? false,
         _readLocal = _Reader(_coreTypes.cellReadLocal),
         _readField = _Reader(_coreTypes.cellReadField),
         _readInitialized = _Reader(_coreTypes.initializedCellRead),
@@ -54,6 +57,26 @@
 
   Nullability get nonNullable => _contextMember.enclosingLibrary.nonNullable;
 
+  bool _shouldLowerVariable(VariableDeclaration variable) => variable.isLate;
+
+  bool _shouldLowerUninitializedVariable(VariableDeclaration variable) =>
+      _shouldLowerVariable(variable) && variable.initializer == null;
+
+  bool _shouldLowerInitializedVariable(VariableDeclaration variable) =>
+      _shouldLowerVariable(variable) && variable.initializer != null;
+
+  bool _shouldLowerStaticField(Field field) =>
+      field.isLate && field.isStatic && field.initializer == null;
+
+  bool _shouldLowerInstanceField(Field field) =>
+      field.isLate && !field.isStatic && _lowerInstanceVariables;
+
+  String _mangleFieldName(Field field) {
+    assert(_shouldLowerInstanceField(field));
+    Class cls = field.parent;
+    return '_#${cls.name}#${field.name.text}';
+  }
+
   void transformAdditionalExports(Library library) {
     List<Reference> additionalExports = library.additionalExports;
     Set<Reference> newExports = {};
@@ -67,7 +90,7 @@
   }
 
   ConstructorInvocation _callCellConstructor(Expression name, int fileOffset) =>
-      omitLateNames
+      _omitLateNames
           ? _callCellUnnamedConstructor(fileOffset)
           : _callCellNamedConstructor(name, fileOffset);
 
@@ -84,7 +107,7 @@
 
   ConstructorInvocation _callInitializedCellConstructor(
           Expression name, Expression initializer, int fileOffset) =>
-      omitLateNames
+      _omitLateNames
           ? _callInitializedCellUnnamedConstructor(initializer, fileOffset)
           : _callInitializedCellNamedConstructor(name, initializer, fileOffset);
 
@@ -125,6 +148,11 @@
           interfaceTarget: _setter)
         ..fileOffset = fileOffset;
 
+  StaticInvocation _callIsSentinel(Expression value, int fileOffset) =>
+      StaticInvocation(_coreTypes.isSentinelMethod,
+          Arguments([value])..fileOffset = fileOffset)
+        ..fileOffset = fileOffset;
+
   void enterFunction() {
     _variableCells.add(null);
   }
@@ -210,8 +238,7 @@
     return _variableCell(variable);
   }
 
-  VariableGet _variableCellAccess(
-      VariableDeclaration variable, int fileOffset) {
+  VariableGet _variableCellRead(VariableDeclaration variable, int fileOffset) {
     assert(_shouldLowerVariable(variable));
     return VariableGet(_variableCell(variable))..fileOffset = fileOffset;
   }
@@ -223,7 +250,7 @@
     if (!_shouldLowerVariable(variable)) return node;
 
     int fileOffset = node.fileOffset;
-    VariableGet cell = _variableCellAccess(variable, fileOffset);
+    VariableGet cell = _variableCellRead(variable, fileOffset);
     _Reader reader = variable.initializer == null
         ? _readLocal
         : (variable.isFinal ? _readInitializedFinal : _readInitialized);
@@ -238,7 +265,7 @@
     if (!_shouldLowerVariable(variable)) return node;
 
     int fileOffset = node.fileOffset;
-    VariableGet cell = _variableCellAccess(variable, fileOffset);
+    VariableGet cell = _variableCellRead(variable, fileOffset);
     Procedure setter = variable.initializer == null
         ? (variable.isFinal
             ? _coreTypes.cellFinalLocalValueSetter
@@ -250,7 +277,7 @@
   }
 
   Field _fieldCell(Field field) {
-    assert(_shouldLowerField(field));
+    assert(_shouldLowerStaticField(field));
     return _fieldCells.putIfAbsent(field, () {
       int fileOffset = field.fileOffset;
       Name name = field.name;
@@ -268,43 +295,261 @@
     });
   }
 
-  StaticGet _fieldCellAccess(Field field, int fileOffset) =>
-      StaticGet(_fieldCell(field))..fileOffset = fileOffset;
+  Field _backingInstanceField(Field field) {
+    assert(_shouldLowerInstanceField(field));
+    return _backingInstanceFields[field] ??=
+        _computeBackingInstanceField(field);
+  }
+
+  Field _computeBackingInstanceField(Field field) {
+    assert(_shouldLowerInstanceField(field));
+    assert(!_backingInstanceFields.containsKey(field));
+    int fileOffset = field.fileOffset;
+    Uri fileUri = field.fileUri;
+    Name name = field.name;
+    String nameText = name.text;
+    DartType type = field.type;
+    Expression initializer = field.initializer;
+    Class enclosingClass = field.enclosingClass;
+
+    Name mangledName = Name(_mangleFieldName(field), field.enclosingLibrary);
+    Field backingField = Field.mutable(mangledName,
+        type: type,
+        initializer: StaticInvocation(_coreTypes.createSentinelMethod,
+            Arguments(const [], types: [type])..fileOffset = fileOffset)
+          ..fileOffset = fileOffset,
+        fileUri: fileUri)
+      ..fileOffset = fileOffset
+      ..isNonNullableByDefault = true
+      ..isInternalImplementation = true;
+    InstanceGet fieldRead() => InstanceGet(InstanceAccessKind.Instance,
+        ThisExpression()..fileOffset = fileOffset, mangledName,
+        interfaceTarget: backingField, resultType: type)
+      ..fileOffset = fileOffset;
+    InstanceSet fieldWrite(Expression value) => InstanceSet(
+        InstanceAccessKind.Instance,
+        ThisExpression()..fileOffset = fileOffset,
+        mangledName,
+        value,
+        interfaceTarget: backingField)
+      ..fileOffset = fileOffset;
+
+    Statement getterBody() {
+      if (initializer == null) {
+        // The lowered getter for `late T field;` and `late final T field;` is
+        //
+        // T get field => _lateReadCheck<T>(this._#field, "field");
+        return ReturnStatement(
+            StaticInvocation(
+                _coreTypes.lateReadCheck,
+                Arguments([fieldRead(), _nameLiteral(nameText, fileOffset)],
+                    types: [type])
+                  ..fileOffset = fileOffset)
+              ..fileOffset = fileOffset)
+          ..fileOffset = fileOffset;
+      } else if (field.isFinal) {
+        // The lowered getter for `late final T field = e;` is
+        //
+        // T get field {
+        //   var value = this._#field;
+        //   if (isSentinel(value)) {
+        //     final result = e;
+        //     _lateInitializeOnceCheck(this._#field, "field");
+        //     value = this._#field = result;
+        //   }
+        //   return value;
+        // }
+        VariableDeclaration value =
+            VariableDeclaration('value', initializer: fieldRead(), type: type)
+              ..fileOffset = fileOffset;
+        VariableGet valueRead() => VariableGet(value)..fileOffset = fileOffset;
+        VariableDeclaration result = VariableDeclaration('result',
+            initializer: initializer, type: type, isFinal: true)
+          ..fileOffset = fileOffset;
+        VariableGet resultRead() =>
+            VariableGet(result)..fileOffset = fileOffset;
+        return Block([
+          value,
+          IfStatement(
+              _callIsSentinel(valueRead(), fileOffset),
+              Block([
+                result,
+                ExpressionStatement(
+                    StaticInvocation(
+                        _coreTypes.lateInitializeOnceCheck,
+                        Arguments(
+                            [fieldRead(), _nameLiteral(nameText, fileOffset)])
+                          ..fileOffset = fileOffset)
+                      ..fileOffset = fileOffset)
+                  ..fileOffset = fileOffset,
+                ExpressionStatement(
+                    VariableSet(value, fieldWrite(resultRead()))
+                      ..fileOffset = fileOffset)
+                  ..fileOffset = fileOffset
+              ])
+                ..fileOffset = fileOffset,
+              null)
+            ..fileOffset = fileOffset,
+          ReturnStatement(valueRead())..fileOffset = fileOffset
+        ])
+          ..fileOffset = fileOffset;
+      } else {
+        // The lowered getter for `late T field = e;` is
+        //
+        // T get field {
+        //   var value = this._#field;
+        //   if (isSentinel(value)) {
+        //     value = this._#field = e;
+        //   }
+        //   return value;
+        // }
+        VariableDeclaration value =
+            VariableDeclaration('value', initializer: fieldRead(), type: type)
+              ..fileOffset = fileOffset;
+        VariableGet valueRead() => VariableGet(value)..fileOffset = fileOffset;
+        return Block([
+          value,
+          IfStatement(
+              _callIsSentinel(valueRead(), fileOffset),
+              ExpressionStatement(
+                  VariableSet(value, fieldWrite(initializer))
+                    ..fileOffset = fileOffset)
+                ..fileOffset = fileOffset,
+              null)
+            ..fileOffset = fileOffset,
+          ReturnStatement(valueRead())..fileOffset = fileOffset
+        ])
+          ..fileOffset = fileOffset;
+      }
+    }
+
+    Procedure getter = Procedure(name, ProcedureKind.Getter,
+        FunctionNode(getterBody(), returnType: type)..fileOffset = fileOffset,
+        fileUri: fileUri, reference: field.getterReference)
+      ..fileOffset = fileOffset
+      ..isNonNullableByDefault = true;
+    enclosingClass.addProcedure(getter);
+    _getterToField[getter] = backingField;
+
+    VariableDeclaration setterValue = VariableDeclaration('value', type: type)
+      ..fileOffset = fileOffset;
+    VariableGet setterValueRead() =>
+        VariableGet(setterValue)..fileOffset = fileOffset;
+
+    Statement setterBody() {
+      if (!field.isFinal) {
+        // The lowered setter for `late T field;` and `late T field = e;` is
+        //
+        // set field(T value) {
+        //   this._#field = value;
+        // }
+        return ExpressionStatement(fieldWrite(setterValueRead()))
+          ..fileOffset = fileOffset;
+      } else if (initializer == null) {
+        // The lowered setter for `late final T field;` is
+        //
+        // set field(T value) {
+        //   _lateWriteOnceCheck(this._#field, "field");
+        //   this._#field = value;
+        // }
+        return Block([
+          ExpressionStatement(
+              StaticInvocation(
+                  _coreTypes.lateWriteOnceCheck,
+                  Arguments([fieldRead(), _nameLiteral(nameText, fileOffset)])
+                    ..fileOffset = fileOffset)
+                ..fileOffset = fileOffset)
+            ..fileOffset = fileOffset,
+          ExpressionStatement(fieldWrite(setterValueRead()))
+            ..fileOffset = fileOffset
+        ])
+          ..fileOffset = fileOffset;
+      } else {
+        // There is no setter for `late final T field = e;`.
+        return null;
+      }
+    }
+
+    Statement body = setterBody();
+    if (body != null) {
+      Procedure setter = Procedure(
+          name,
+          ProcedureKind.Setter,
+          FunctionNode(body,
+              positionalParameters: [setterValue], returnType: VoidType())
+            ..fileOffset = fileOffset,
+          fileUri: fileUri,
+          reference: field.setterReference)
+        ..fileOffset = fileOffset
+        ..isNonNullableByDefault = true;
+      enclosingClass.addProcedure(setter);
+    }
+
+    return backingField;
+  }
 
   TreeNode transformField(Field field, Member contextMember) {
     _contextMember = contextMember;
 
-    if (!_shouldLowerField(field)) return field;
+    if (_shouldLowerStaticField(field)) return _fieldCell(field);
+    if (_shouldLowerInstanceField(field)) return _backingInstanceField(field);
 
-    return _fieldCell(field);
+    return field;
   }
 
+  TreeNode transformFieldInitializer(
+      FieldInitializer initializer, Member contextMember) {
+    _contextMember = contextMember;
+
+    // If the [Field] has been lowered, we can't use `node.field` to retrieve it
+    // because the `getterReference` of the original field now points to the new
+    // getter for the backing field.
+    // TODO(fishythefish): Clean this up when [FieldInitializer] maintains a
+    // correct [Reference] to its [Field].
+    NamedNode node = initializer.fieldReference.node;
+    assert(node != null);
+    Field backingField;
+    if (node is Field) {
+      if (!_shouldLowerInstanceField(node)) return initializer;
+      backingField = _backingInstanceField(node);
+    } else {
+      backingField = _getterToField[node];
+    }
+    assert(backingField != null);
+
+    return FieldInitializer(backingField, initializer.value)
+      ..fileOffset = initializer.fileOffset;
+  }
+
+  StaticGet _fieldCellAccess(Field field, int fileOffset) =>
+      StaticGet(_fieldCell(field))..fileOffset = fileOffset;
+
   TreeNode transformStaticGet(StaticGet node, Member contextMember) {
     _contextMember = contextMember;
 
     Member target = node.target;
-    if (target is Field && _shouldLowerField(target)) {
+    if (target is Field && _shouldLowerStaticField(target)) {
       int fileOffset = node.fileOffset;
       StaticGet cell = _fieldCellAccess(target, fileOffset);
       return _callReader(_readField, cell, target.type, fileOffset);
-    } else {
-      return node;
     }
+
+    return node;
   }
 
   TreeNode transformStaticSet(StaticSet node, Member contextMember) {
     _contextMember = contextMember;
 
     Member target = node.target;
-    if (target is Field && _shouldLowerField(target)) {
+    if (target is Field && _shouldLowerStaticField(target)) {
       int fileOffset = node.fileOffset;
       StaticGet cell = _fieldCellAccess(target, fileOffset);
       Procedure setter = target.isFinal
           ? _coreTypes.cellFinalFieldValueSetter
           : _coreTypes.cellValueSetter;
       return _callSetter(setter, cell, node.value, fileOffset);
-    } else {
-      return node;
     }
+
+    return node;
   }
 }
diff --git a/pkg/compiler/lib/src/kernel/transformations/lowering.dart b/pkg/compiler/lib/src/kernel/transformations/lowering.dart
index f8726e9..e9cad5b 100644
--- a/pkg/compiler/lib/src/kernel/transformations/lowering.dart
+++ b/pkg/compiler/lib/src/kernel/transformations/lowering.dart
@@ -5,6 +5,8 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/core_types.dart' show CoreTypes;
+
+import '../../options.dart';
 import 'factory_specializer.dart';
 import 'late_lowering.dart';
 
@@ -13,12 +15,9 @@
 ///
 /// Each transformation is applied locally to AST nodes of certain types after
 /// transforming children nodes.
-void transformLibraries(
-    List<Library> libraries, CoreTypes coreTypes, ClassHierarchy hierarchy,
-    {bool omitLateNames}) {
-  assert(omitLateNames != null);
-  final transformer =
-      _Lowering(coreTypes, hierarchy, omitLateNames: omitLateNames);
+void transformLibraries(List<Library> libraries, CoreTypes coreTypes,
+    ClassHierarchy hierarchy, CompilerOptions options) {
+  final transformer = _Lowering(coreTypes, hierarchy, options);
   libraries.forEach(transformer.visitLibrary);
 
   // Do a second pass to remove/replace now-unused nodes.
@@ -34,10 +33,10 @@
 
   Member _currentMember;
 
-  _Lowering(CoreTypes coreTypes, ClassHierarchy hierarchy, {bool omitLateNames})
-      : assert(omitLateNames != null),
-        factorySpecializer = FactorySpecializer(coreTypes, hierarchy),
-        _lateLowering = LateLowering(coreTypes, omitLateNames: omitLateNames);
+  _Lowering(
+      CoreTypes coreTypes, ClassHierarchy hierarchy, CompilerOptions _options)
+      : factorySpecializer = FactorySpecializer(coreTypes, hierarchy),
+        _lateLowering = LateLowering(coreTypes, _options);
 
   void transformAdditionalExports(Library node) {
     _lateLowering.transformAdditionalExports(node);
@@ -89,6 +88,12 @@
   }
 
   @override
+  TreeNode visitFieldInitializer(FieldInitializer node) {
+    node.transformChildren(this);
+    return _lateLowering.transformFieldInitializer(node, _currentMember);
+  }
+
+  @override
   TreeNode visitStaticGet(StaticGet node) {
     node.transformChildren(this);
     return _lateLowering.transformStaticGet(node, _currentMember);
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index a37a9c8..1133c6d 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -400,6 +400,10 @@
   /// called.
   bool experimentCallInstrumentation = false;
 
+  /// Use the dart2js lowering of late instance variables rather than the CFE
+  /// lowering.
+  bool experimentLateInstanceVariables = false;
+
   /// When null-safety is enabled, whether the compiler should emit code with
   /// unsound or sound semantics.
   ///
@@ -518,6 +522,8 @@
           _hasOption(options, Flags.experimentUnreachableMethodsThrow)
       ..experimentCallInstrumentation =
           _hasOption(options, Flags.experimentCallInstrumentation)
+      ..experimentLateInstanceVariables =
+          _hasOption(options, Flags.experimentLateInstanceVariables)
       ..generateSourceMap = !_hasOption(options, Flags.noSourceMaps)
       ..outputUri = _extractUriOption(options, '--out=')
       ..platformBinaries = platformBinaries
diff --git a/pkg/js_runtime/lib/shared/async_await_error_codes.dart b/pkg/js_runtime/lib/shared/async_await_error_codes.dart
index f87406b..1708230 100644
--- a/pkg/js_runtime/lib/shared/async_await_error_codes.dart
+++ b/pkg/js_runtime/lib/shared/async_await_error_codes.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.12
+
 /// Contains error codes that transformed async/async* functions use to
 /// communicate with js_helper functions.
 
diff --git a/pkg/js_runtime/lib/shared/embedded_names.dart b/pkg/js_runtime/lib/shared/embedded_names.dart
index e2dd66d..6d6de2d 100644
--- a/pkg/js_runtime/lib/shared/embedded_names.dart
+++ b/pkg/js_runtime/lib/shared/embedded_names.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.12
+
 /// Contains the names of globals that are embedded into the output by the
 /// compiler.
 ///
diff --git a/pkg/js_runtime/lib/shared/recipe_syntax.dart b/pkg/js_runtime/lib/shared/recipe_syntax.dart
index c183861..7305491 100644
--- a/pkg/js_runtime/lib/shared/recipe_syntax.dart
+++ b/pkg/js_runtime/lib/shared/recipe_syntax.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.12
+
 /// Constants and predicates used for encoding and decoding type recipes.
 ///
 /// This library is shared between the compiler and the runtime system.
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index d44801ec..baa6659 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -371,6 +371,15 @@
   late final Procedure initializedCellFinalValueSetter = index.getMember(
       'dart:_late_helper', '_InitializedCell', 'set:finalValue') as Procedure;
 
+  late final Procedure lateReadCheck =
+      index.getTopLevelProcedure('dart:_late_helper', '_lateReadCheck');
+
+  late final Procedure lateWriteOnceCheck =
+      index.getTopLevelProcedure('dart:_late_helper', '_lateWriteOnceCheck');
+
+  late final Procedure lateInitializeOnceCheck = index.getTopLevelProcedure(
+      'dart:_late_helper', '_lateInitializeOnceCheck');
+
   InterfaceType get objectLegacyRawType {
     return _objectLegacyRawType ??= _legacyRawTypes[objectClass] ??=
         new InterfaceType(objectClass, Nullability.legacy, const <DartType>[]);
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 47f3893..1613626 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,4 +1,9 @@
 # Changelog
+
+## 7.1.0
+- Update to version `3.46` of the spec.
+- Move `sourcePosition` properties into `ClassRef`, `FieldRef`, and `FuncRef`.
+
 ## 7.0.0
 - *breaking bug fix*: Fixed issue where response parsing could fail for `Context`.
 - Add support for `setBreakpointState` RPC and updated `Breakpoint` class to include
diff --git a/pkg/vm_service/example/vm_service_assert.dart b/pkg/vm_service/example/vm_service_assert.dart
index c861f82..f9f2d6e 100644
--- a/pkg/vm_service/example/vm_service_assert.dart
+++ b/pkg/vm_service/example/vm_service_assert.dart
@@ -317,6 +317,7 @@
   assertNotNull(obj);
   assertString(obj.id!);
   assertString(obj.name!);
+  assertLibraryRef(obj.library!);
   return obj;
 }
 
@@ -331,10 +332,10 @@
   assertNotNull(obj);
   assertString(obj.id!);
   assertString(obj.name!);
+  assertLibraryRef(obj.library!);
   assertBool(obj.isAbstract!);
   assertBool(obj.isConst!);
   assertBool(obj.traceAllocations!);
-  assertLibraryRef(obj.library!);
   assertListOfInstanceRef(obj.interfaces!);
   assertListOfFieldRef(obj.fields!);
   assertListOfFuncRef(obj.functions!);
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index d934516..9e3fb90 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.45
+version=3.46
diff --git a/pkg/vm_service/lib/src/dart_io_extensions.dart b/pkg/vm_service/lib/src/dart_io_extensions.dart
index 73b3b84..9e9faaf 100644
--- a/pkg/vm_service/lib/src/dart_io_extensions.dart
+++ b/pkg/vm_service/lib/src/dart_io_extensions.dart
@@ -485,7 +485,7 @@
   HttpProfileRequestData.buildErrorRequest({
     required this.error,
     required this.events,
-  })   : _connectionInfo = null,
+  })  : _connectionInfo = null,
         _contentLength = null,
         _cookies = [],
         _followRedirects = null,
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index a42219a..a460c69 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -26,7 +26,7 @@
         HeapSnapshotObjectNoData,
         HeapSnapshotObjectNullData;
 
-const String vmServiceVersion = '3.45.0';
+const String vmServiceVersion = '3.46.0';
 
 /// @optional
 const String optional = 'optional';
@@ -2690,8 +2690,8 @@
                 as List? ??
             []);
     memoryUsage =
-        createServiceObject(json['memoryUsage']!, const ['MemoryUsage'])
-            as MemoryUsage;
+        createServiceObject(json['memoryUsage'], const ['MemoryUsage'])
+            as MemoryUsage?;
     dateLastAccumulatorReset = json['dateLastAccumulatorReset'] is String
         ? int.parse(json['dateLastAccumulatorReset'])
         : json['dateLastAccumulatorReset'];
@@ -2743,9 +2743,9 @@
   });
 
   BoundField._fromJson(Map<String, dynamic> json) {
-    decl = createServiceObject(json['decl']!, const ['FieldRef']) as FieldRef;
+    decl = createServiceObject(json['decl'], const ['FieldRef']) as FieldRef?;
     value =
-        createServiceObject(json['value']!, const ['InstanceRef', 'Sentinel'])
+        createServiceObject(json['value'], const ['InstanceRef', 'Sentinel'])
             as dynamic;
   }
 
@@ -2800,7 +2800,7 @@
 
   BoundVariable._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
-    value = createServiceObject(json['value']!,
+    value = createServiceObject(json['value'],
         const ['InstanceRef', 'TypeArgumentsRef', 'Sentinel']) as dynamic;
     declarationTokenPos = json['declarationTokenPos'] ?? -1;
     scopeStartTokenPos = json['scopeStartTokenPos'] ?? -1;
@@ -2875,7 +2875,7 @@
     enabled = json['enabled'] ?? false;
     resolved = json['resolved'] ?? false;
     isSyntheticAsyncContinuation = json['isSyntheticAsyncContinuation'];
-    location = createServiceObject(json['location']!,
+    location = createServiceObject(json['location'],
         const ['SourceLocation', 'UnresolvedSourceLocation']) as dynamic;
   }
 
@@ -2914,15 +2914,28 @@
   /// The name of this class.
   String? name;
 
+  /// The location of this class in the source code.
+  @optional
+  SourceLocation? location;
+
+  /// The library which contains this class.
+  LibraryRef? library;
+
   ClassRef({
     required this.name,
+    required this.library,
     required String id,
+    this.location,
   }) : super(
           id: id,
         );
 
   ClassRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
+    location = createServiceObject(json['location'], const ['SourceLocation'])
+        as SourceLocation?;
+    library = createServiceObject(json['library'], const ['LibraryRef'])
+        as LibraryRef?;
   }
 
   @override
@@ -2934,7 +2947,9 @@
     json['type'] = type;
     json.addAll({
       'name': name,
+      'library': library?.toJson(),
     });
+    _setIfNotNull(json, 'location', location?.toJson());
     return json;
   }
 
@@ -2942,7 +2957,8 @@
 
   operator ==(other) => other is ClassRef && id == other.id;
 
-  String toString() => '[ClassRef id: ${id}, name: ${name}]';
+  String toString() =>
+      '[ClassRef id: ${id}, name: ${name}, library: ${library}]';
 }
 
 /// A `Class` provides information about a Dart language class.
@@ -2953,6 +2969,13 @@
   /// The name of this class.
   String? name;
 
+  /// The location of this class in the source code.
+  @optional
+  SourceLocation? location;
+
+  /// The library which contains this class.
+  LibraryRef? library;
+
   /// The error which occurred during class finalization, if it exists.
   @optional
   ErrorRef? error;
@@ -2966,13 +2989,6 @@
   /// Are allocations of this class being traced?
   bool? traceAllocations;
 
-  /// The library which contains this class.
-  LibraryRef? library;
-
-  /// The location of this class in the source code.
-  @optional
-  SourceLocation? location;
-
   /// The superclass of this class, if any.
   @optional
   ClassRef? superClass;
@@ -3006,17 +3022,17 @@
 
   Class({
     required this.name,
+    required this.library,
     required this.isAbstract,
     required this.isConst,
     required this.traceAllocations,
-    required this.library,
     required this.interfaces,
     required this.fields,
     required this.functions,
     required this.subclasses,
     required String id,
-    this.error,
     this.location,
+    this.error,
     this.superClass,
     this.superType,
     this.mixin,
@@ -3026,14 +3042,14 @@
 
   Class._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
+    location = createServiceObject(json['location'], const ['SourceLocation'])
+        as SourceLocation?;
+    library = createServiceObject(json['library'], const ['LibraryRef'])
+        as LibraryRef?;
     error = createServiceObject(json['error'], const ['ErrorRef']) as ErrorRef?;
     isAbstract = json['abstract'] ?? false;
     isConst = json['const'] ?? false;
     traceAllocations = json['traceAllocations'] ?? false;
-    library = createServiceObject(json['library']!, const ['LibraryRef'])
-        as LibraryRef;
-    location = createServiceObject(json['location'], const ['SourceLocation'])
-        as SourceLocation?;
     superClass =
         createServiceObject(json['super'], const ['ClassRef']) as ClassRef?;
     superType = createServiceObject(json['superType'], const ['InstanceRef'])
@@ -3063,17 +3079,17 @@
     json['type'] = type;
     json.addAll({
       'name': name,
+      'library': library?.toJson(),
       'abstract': isAbstract,
       'const': isConst,
       'traceAllocations': traceAllocations,
-      'library': library?.toJson(),
       'interfaces': interfaces?.map((f) => f.toJson()).toList(),
       'fields': fields?.map((f) => f.toJson()).toList(),
       'functions': functions?.map((f) => f.toJson()).toList(),
       'subclasses': subclasses?.map((f) => f.toJson()).toList(),
     });
-    _setIfNotNull(json, 'error', error?.toJson());
     _setIfNotNull(json, 'location', location?.toJson());
+    _setIfNotNull(json, 'error', error?.toJson());
     _setIfNotNull(json, 'super', superClass?.toJson());
     _setIfNotNull(json, 'superType', superType?.toJson());
     _setIfNotNull(json, 'mixin', mixin?.toJson());
@@ -3118,7 +3134,7 @@
 
   ClassHeapStats._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     classRef =
-        createServiceObject(json['class']!, const ['ClassRef']) as ClassRef;
+        createServiceObject(json['class'], const ['ClassRef']) as ClassRef?;
     accumulatedSize = json['accumulatedSize'] ?? -1;
     bytesCurrent = json['bytesCurrent'] ?? -1;
     instancesAccumulated = json['instancesAccumulated'] ?? -1;
@@ -3378,7 +3394,7 @@
 
   ContextElement._fromJson(Map<String, dynamic> json) {
     value =
-        createServiceObject(json['value']!, const ['InstanceRef', 'Sentinel'])
+        createServiceObject(json['value'], const ['InstanceRef', 'Sentinel'])
             as dynamic;
   }
 
@@ -4015,6 +4031,10 @@
   /// Is this field static?
   bool? isStatic;
 
+  /// The location of this field in the source code.
+  @optional
+  SourceLocation? location;
+
   FieldRef({
     required this.name,
     required this.owner,
@@ -4023,19 +4043,22 @@
     required this.isFinal,
     required this.isStatic,
     required String id,
+    this.location,
   }) : super(
           id: id,
         );
 
   FieldRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
-    owner = createServiceObject(json['owner']!, const ['ObjRef']) as ObjRef;
+    owner = createServiceObject(json['owner'], const ['ObjRef']) as ObjRef?;
     declaredType =
-        createServiceObject(json['declaredType']!, const ['InstanceRef'])
-            as InstanceRef;
+        createServiceObject(json['declaredType'], const ['InstanceRef'])
+            as InstanceRef?;
     isConst = json['const'] ?? false;
     isFinal = json['final'] ?? false;
     isStatic = json['static'] ?? false;
+    location = createServiceObject(json['location'], const ['SourceLocation'])
+        as SourceLocation?;
   }
 
   @override
@@ -4053,6 +4076,7 @@
       'final': isFinal,
       'static': isStatic,
     });
+    _setIfNotNull(json, 'location', location?.toJson());
     return json;
   }
 
@@ -4091,6 +4115,10 @@
   /// Is this field static?
   bool? isStatic;
 
+  /// The location of this field in the source code.
+  @optional
+  SourceLocation? location;
+
   /// The value of this field, if the field is static. If uninitialized, this
   /// will take the value of an uninitialized Sentinel.
   ///
@@ -4098,10 +4126,6 @@
   @optional
   dynamic staticValue;
 
-  /// The location of this field in the source code.
-  @optional
-  SourceLocation? location;
-
   Field({
     required this.name,
     required this.owner,
@@ -4110,25 +4134,25 @@
     required this.isFinal,
     required this.isStatic,
     required String id,
-    this.staticValue,
     this.location,
+    this.staticValue,
   }) : super(
           id: id,
         );
 
   Field._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
-    owner = createServiceObject(json['owner']!, const ['ObjRef']) as ObjRef;
+    owner = createServiceObject(json['owner'], const ['ObjRef']) as ObjRef?;
     declaredType =
-        createServiceObject(json['declaredType']!, const ['InstanceRef'])
-            as InstanceRef;
+        createServiceObject(json['declaredType'], const ['InstanceRef'])
+            as InstanceRef?;
     isConst = json['const'] ?? false;
     isFinal = json['final'] ?? false;
     isStatic = json['static'] ?? false;
-    staticValue = createServiceObject(
-        json['staticValue'], const ['InstanceRef', 'Sentinel']) as dynamic;
     location = createServiceObject(json['location'], const ['SourceLocation'])
         as SourceLocation?;
+    staticValue = createServiceObject(
+        json['staticValue'], const ['InstanceRef', 'Sentinel']) as dynamic;
   }
 
   @override
@@ -4146,8 +4170,8 @@
       'final': isFinal,
       'static': isStatic,
     });
-    _setIfNotNull(json, 'staticValue', staticValue?.toJson());
     _setIfNotNull(json, 'location', location?.toJson());
+    _setIfNotNull(json, 'staticValue', staticValue?.toJson());
     return json;
   }
 
@@ -4328,12 +4352,17 @@
   /// Is this function const?
   bool? isConst;
 
+  /// The location of this function in the source code.
+  @optional
+  SourceLocation? location;
+
   FuncRef({
     required this.name,
     required this.owner,
     required this.isStatic,
     required this.isConst,
     required String id,
+    this.location,
   }) : super(
           id: id,
         );
@@ -4341,9 +4370,11 @@
   FuncRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
     owner = createServiceObject(
-        json['owner']!, const ['LibraryRef', 'ClassRef', 'FuncRef']) as dynamic;
+        json['owner'], const ['LibraryRef', 'ClassRef', 'FuncRef']) as dynamic;
     isStatic = json['static'] ?? false;
     isConst = json['const'] ?? false;
+    location = createServiceObject(json['location'], const ['SourceLocation'])
+        as SourceLocation?;
   }
 
   @override
@@ -4359,6 +4390,7 @@
       'static': isStatic,
       'const': isConst,
     });
+    _setIfNotNull(json, 'location', location?.toJson());
     return json;
   }
 
@@ -4413,7 +4445,7 @@
   Func._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     name = json['name'] ?? '';
     owner = createServiceObject(
-        json['owner']!, const ['LibraryRef', 'ClassRef', 'FuncRef']) as dynamic;
+        json['owner'], const ['LibraryRef', 'ClassRef', 'FuncRef']) as dynamic;
     isStatic = json['static'] ?? false;
     isConst = json['const'] ?? false;
     location = createServiceObject(json['location'], const ['SourceLocation'])
@@ -4600,7 +4632,7 @@
     kind = json['kind'] ?? '';
     identityHashCode = json['identityHashCode'] ?? -1;
     classRef =
-        createServiceObject(json['class']!, const ['ClassRef']) as ClassRef;
+        createServiceObject(json['class'], const ['ClassRef']) as ClassRef?;
     valueAsString = json['valueAsString'];
     valueAsStringIsTruncated = json['valueAsStringIsTruncated'];
     length = json['length'];
@@ -4984,7 +5016,7 @@
     kind = json['kind'] ?? '';
     identityHashCode = json['identityHashCode'] ?? -1;
     classRef =
-        createServiceObject(json['class']!, const ['ClassRef']) as ClassRef;
+        createServiceObject(json['class'], const ['ClassRef']) as ClassRef?;
     valueAsString = json['valueAsString'];
     valueAsStringIsTruncated = json['valueAsStringIsTruncated'];
     length = json['length'];
@@ -5250,7 +5282,7 @@
     livePorts = json['livePorts'] ?? -1;
     pauseOnExit = json['pauseOnExit'] ?? false;
     pauseEvent =
-        createServiceObject(json['pauseEvent']!, const ['Event']) as Event;
+        createServiceObject(json['pauseEvent'], const ['Event']) as Event?;
     rootLib = createServiceObject(json['rootLib'], const ['LibraryRef'])
         as LibraryRef?;
     libraries = List<LibraryRef>.from(
@@ -5519,7 +5551,7 @@
   });
 
   InboundReference._fromJson(Map<String, dynamic> json) {
-    source = createServiceObject(json['source']!, const ['ObjRef']) as ObjRef;
+    source = createServiceObject(json['source'], const ['ObjRef']) as ObjRef?;
     parentListIndex = json['parentListIndex'];
     parentField = createServiceObject(json['parentField'], const ['FieldRef'])
         as FieldRef?;
@@ -5744,8 +5776,8 @@
     isImport = json['isImport'] ?? false;
     isDeferred = json['isDeferred'] ?? false;
     prefix = json['prefix'] ?? '';
-    target = createServiceObject(json['target']!, const ['LibraryRef'])
-        as LibraryRef;
+    target = createServiceObject(json['target'], const ['LibraryRef'])
+        as LibraryRef?;
   }
 
   Map<String, dynamic> toJson() {
@@ -5807,19 +5839,19 @@
   });
 
   LogRecord._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
-    message = createServiceObject(json['message']!, const ['InstanceRef'])
-        as InstanceRef;
+    message = createServiceObject(json['message'], const ['InstanceRef'])
+        as InstanceRef?;
     time = json['time'] ?? -1;
     level = json['level'] ?? -1;
     sequenceNumber = json['sequenceNumber'] ?? -1;
-    loggerName = createServiceObject(json['loggerName']!, const ['InstanceRef'])
-        as InstanceRef;
-    zone = createServiceObject(json['zone']!, const ['InstanceRef'])
-        as InstanceRef;
-    error = createServiceObject(json['error']!, const ['InstanceRef'])
-        as InstanceRef;
-    stackTrace = createServiceObject(json['stackTrace']!, const ['InstanceRef'])
-        as InstanceRef;
+    loggerName = createServiceObject(json['loggerName'], const ['InstanceRef'])
+        as InstanceRef?;
+    zone = createServiceObject(json['zone'], const ['InstanceRef'])
+        as InstanceRef?;
+    error = createServiceObject(json['error'], const ['InstanceRef'])
+        as InstanceRef?;
+    stackTrace = createServiceObject(json['stackTrace'], const ['InstanceRef'])
+        as InstanceRef?;
   }
 
   @override
@@ -5861,10 +5893,10 @@
   });
 
   MapAssociation._fromJson(Map<String, dynamic> json) {
-    key = createServiceObject(json['key']!, const ['InstanceRef', 'Sentinel'])
+    key = createServiceObject(json['key'], const ['InstanceRef', 'Sentinel'])
         as dynamic;
     value =
-        createServiceObject(json['value']!, const ['InstanceRef', 'Sentinel'])
+        createServiceObject(json['value'], const ['InstanceRef', 'Sentinel'])
             as dynamic;
   }
 
@@ -6051,6 +6083,11 @@
           kind: InstanceKind.kNull,
           classRef: ClassRef(
             id: 'class/null',
+            library: LibraryRef(
+              id: '',
+              name: 'dart:core',
+              uri: 'dart:core',
+            ),
             name: 'Null',
           ),
         );
@@ -6098,6 +6135,11 @@
           kind: InstanceKind.kNull,
           classRef: ClassRef(
             id: 'class/null',
+            library: LibraryRef(
+              id: '',
+              name: 'dart:core',
+              uri: 'dart:core',
+            ),
             name: 'Null',
           ),
         );
@@ -6323,7 +6365,7 @@
     exclusiveTicks = json['exclusiveTicks'] ?? -1;
     resolvedUrl = json['resolvedUrl'] ?? '';
     function =
-        createServiceObject(json['function']!, const ['dynamic']) as dynamic;
+        createServiceObject(json['function'], const ['dynamic']) as dynamic;
   }
 
   Map<String, dynamic> toJson() {
@@ -6433,8 +6475,8 @@
 
   ProcessMemoryUsage._fromJson(Map<String, dynamic> json)
       : super._fromJson(json) {
-    root = createServiceObject(json['root']!, const ['ProcessMemoryItem'])
-        as ProcessMemoryItem;
+    root = createServiceObject(json['root'], const ['ProcessMemoryItem'])
+        as ProcessMemoryItem?;
   }
 
   @override
@@ -6562,7 +6604,7 @@
   });
 
   RetainingObject._fromJson(Map<String, dynamic> json) {
-    value = createServiceObject(json['value']!, const ['ObjRef']) as ObjRef;
+    value = createServiceObject(json['value'], const ['ObjRef']) as ObjRef?;
     parentListIndex = json['parentListIndex'];
     parentMapKey =
         createServiceObject(json['parentMapKey'], const ['ObjRef']) as ObjRef?;
@@ -6810,8 +6852,8 @@
 
   Script._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     uri = json['uri'] ?? '';
-    library = createServiceObject(json['library']!, const ['LibraryRef'])
-        as LibraryRef;
+    library = createServiceObject(json['library'], const ['LibraryRef'])
+        as LibraryRef?;
     lineOffset = json['lineOffset'];
     columnOffset = json['columnOffset'];
     source = json['source'];
@@ -6932,7 +6974,7 @@
 
   SourceLocation._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
     script =
-        createServiceObject(json['script']!, const ['ScriptRef']) as ScriptRef;
+        createServiceObject(json['script'], const ['ScriptRef']) as ScriptRef?;
     tokenPos = json['tokenPos'] ?? -1;
     endTokenPos = json['endTokenPos'];
   }
@@ -7235,7 +7277,7 @@
   static Timeline? parse(Map<String, dynamic>? json) =>
       json == null ? null : Timeline._fromJson(json);
 
-  /// A list of timeline events. No order is guarenteed for these events; in
+  /// A list of timeline events. No order is guaranteed for these events; in
   /// particular, these events may be unordered with respect to their
   /// timestamps.
   List<TimelineEvent>? traceEvents;
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index a7db2e8..9ea0b77 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@
   A library to communicate with a service implementing the Dart VM
   service protocol.
 
-version: 7.0.0
+version: 7.1.0
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index 5e348b1..0f9897f 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -1491,6 +1491,8 @@
       gen.writeln('identityHashCode: 0,');
       gen.writeln('kind: InstanceKind.kNull,');
       gen.writeln("classRef: ClassRef(id: 'class/null',");
+      gen.writeln("library: LibraryRef(id: '', name: 'dart:core',");
+      gen.writeln("uri: 'dart:core',),");
       gen.writeln("name: 'Null',),");
       gen.writeln(')');
     }
@@ -1640,10 +1642,9 @@
         }
       } else {
         String typesList = _typeRefListToString(field.type.types);
-        String nullable =
-            field.optional && field.type.name != 'dynamic' ? '?' : '';
+        String nullable = field.type.name != 'dynamic' ? '?' : '';
         gen.writeln("${field.generatableName} = "
-            "createServiceObject(json['${field.name}']${field.optional ? '' : '!'}, "
+            "createServiceObject(json['${field.name}'], "
             "$typesList) as ${field.type.name}$nullable;");
       }
     });
diff --git a/pkg/wasm/analysis_options.yaml b/pkg/wasm/analysis_options.yaml
index 486705d..2bb8d1d 100644
--- a/pkg/wasm/analysis_options.yaml
+++ b/pkg/wasm/analysis_options.yaml
@@ -1 +1,65 @@
 include: package:pedantic/analysis_options.1.9.0.yaml
+
+analyzer:
+  strong-mode:
+    implicit-casts: false
+
+linter:
+  rules:
+  - avoid_catching_errors
+  #- avoid_dynamic_calls
+  - avoid_function_literals_in_foreach_calls
+  - avoid_private_typedef_functions
+  - avoid_redundant_argument_values
+  - avoid_renaming_method_parameters
+  - avoid_returning_null_for_void
+  - avoid_unused_constructor_parameters
+  - await_only_futures
+  - camel_case_types
+  - cascade_invocations
+  - constant_identifier_names
+  - directives_ordering
+  - empty_statements
+  - file_names
+  - implementation_imports
+  - iterable_contains_unrelated_type
+  - join_return_with_assignment
+  - lines_longer_than_80_chars
+  - list_remove_unrelated_type
+  - missing_whitespace_between_adjacent_strings
+  - no_runtimeType_toString
+  - non_constant_identifier_names
+  - only_throw_errors
+  - overridden_fields
+  - package_names
+  - package_prefixed_library_names
+  - prefer_asserts_in_initializer_lists
+  - prefer_const_constructors
+  - prefer_const_declarations
+  - prefer_expression_function_bodies
+  - prefer_function_declarations_over_variables
+  - prefer_if_null_operators
+  - prefer_initializing_formals
+  - prefer_inlined_adds
+  - prefer_interpolation_to_compose_strings
+  - prefer_is_not_operator
+  - prefer_null_aware_operators
+  - prefer_relative_imports
+  - prefer_typing_uninitialized_variables
+  - prefer_void_to_null
+  - provide_deprecation_message
+  - require_trailing_commas
+  - sort_pub_dependencies
+  - test_types_in_equals
+  - throw_in_finally
+  - type_annotate_public_apis
+  - unnecessary_brace_in_string_interps
+  - unnecessary_lambdas
+  - unnecessary_null_aware_assignments
+  - unnecessary_overrides
+  - unnecessary_parenthesis
+  - unnecessary_statements
+  - unnecessary_string_interpolations
+  - use_is_even_rather_than_modulo
+  - use_string_buffers
+  - void_checks
diff --git a/pkg/wasm/bin/setup.dart b/pkg/wasm/bin/setup.dart
index badaac9..04fc145 100644
--- a/pkg/wasm/bin/setup.dart
+++ b/pkg/wasm/bin/setup.dart
@@ -64,19 +64,19 @@
       .transform(utf8.decoder)
       .transform(const LineSplitter())
       .listen((line) => stderr.writeln(line));
-  final cfg = {};
+  final cfg = <String, String?>{};
   await process.stdout
       .transform(utf8.decoder)
       .transform(const LineSplitter())
       .listen((line) {
     final match = RegExp(r'^([^=]+)="(.*)"$').firstMatch(line);
-    if (match != null) cfg[match.group(1)] = match.group(2);
+    if (match != null) cfg[match.group(1)!] = match.group(2);
   }).asFuture();
-  String arch = cfg['target_arch'] ?? 'unknown';
-  String vendor = cfg['target_vendor'] ?? 'unknown';
-  String os = cfg['target_os'] ?? 'unknown';
+  var arch = cfg['target_arch'] ?? 'unknown';
+  var vendor = cfg['target_vendor'] ?? 'unknown';
+  var os = cfg['target_os'] ?? 'unknown';
   if (os == 'macos') os = 'darwin';
-  String? env = cfg['target_env'];
+  var env = cfg['target_env'];
   return [arch, vendor, os, env]
       .where((element) => element != null && element.isNotEmpty)
       .join('-');
@@ -88,14 +88,14 @@
   process.stdout
       .transform(utf8.decoder)
       .transform(const LineSplitter())
-      .listen((line) => print(line));
+      .listen(print);
   process.stderr
       .transform(utf8.decoder)
       .transform(const LineSplitter())
       .listen((line) => stderr.writeln(line));
   final exitCode = await process.exitCode;
   if (exitCode != 0) {
-    print('Command failed with exit code ${exitCode}');
+    print('Command failed with exit code $exitCode');
     exit(exitCode);
   }
 }
@@ -188,7 +188,7 @@
     target,
     outDir.resolve('dart_api_dl.o').path,
     outDir.resolve('finalizers.o').path,
-    outDir.resolve('' + target + '/release/libwasmer.a').path,
+    outDir.resolve('$target/release/libwasmer.a').path,
     '-o',
     outLib
   ]);
diff --git a/pkg/wasm/example/brotli.dart b/pkg/wasm/example/brotli.dart
index 726c333..f91e434 100644
--- a/pkg/wasm/example/brotli.dart
+++ b/pkg/wasm/example/brotli.dart
@@ -43,14 +43,23 @@
 
   memoryView.setRange(inputPtr, inputPtr + inputData.length, inputData);
 
-  var sizeBytes = ByteData(4);
-  sizeBytes.setUint32(0, inputData.length, Endian.host);
+  var sizeBytes = ByteData(4)..setUint32(0, inputData.length, Endian.host);
   memoryView.setRange(
-      outSizePtr, outSizePtr + 4, sizeBytes.buffer.asUint8List());
+    outSizePtr,
+    outSizePtr + 4,
+    sizeBytes.buffer.asUint8List(),
+  );
 
   print('\nCompressing...');
-  var status = compress(kDefaultQuality, kDefaultWindow, kDefaultMode,
-      inputData.length, inputPtr, outSizePtr, outputPtr);
+  var status = compress(
+    kDefaultQuality,
+    kDefaultWindow,
+    kDefaultMode,
+    inputData.length,
+    inputPtr,
+    outSizePtr,
+    outputPtr,
+  );
   print('Compression status: $status');
 
   var compressedSize =
@@ -60,10 +69,12 @@
   var spaceSaving = 100 * (1 - compressedSize / inputData.length);
   print('Space saving: ${spaceSaving.toStringAsFixed(2)}%');
 
-  var decSizeBytes = ByteData(4);
-  decSizeBytes.setUint32(0, inputData.length, Endian.host);
+  var decSizeBytes = ByteData(4)..setUint32(0, inputData.length, Endian.host);
   memoryView.setRange(
-      decSizePtr, decSizePtr + 4, decSizeBytes.buffer.asUint8List());
+    decSizePtr,
+    decSizePtr + 4,
+    decSizeBytes.buffer.asUint8List(),
+  );
 
   print('\nDecompressing...');
   status = decompress(compressedSize, outputPtr, decSizePtr, decodedPtr);
diff --git a/pkg/wasm/lib/src/function.dart b/pkg/wasm/lib/src/function.dart
index 3816e59..9beb559 100644
--- a/pkg/wasm/lib/src/function.dart
+++ b/pkg/wasm/lib/src/function.dart
@@ -31,9 +31,8 @@
   }
 
   @override
-  String toString() {
-    return WasmRuntime.getSignatureString(_name, _argTypes, _returnType);
-  }
+  String toString() =>
+      WasmRuntime.getSignatureString(_name, _argTypes, _returnType);
 
   bool _fillArg(dynamic arg, int i) {
     switch (_argTypes[i]) {
diff --git a/pkg/wasm/lib/src/module.dart b/pkg/wasm/lib/src/module.dart
index 8e71597..ab0b960 100644
--- a/pkg/wasm/lib/src/module.dart
+++ b/pkg/wasm/lib/src/module.dart
@@ -25,15 +25,12 @@
 
   /// Returns a WasmInstanceBuilder that is used to add all the imports that the
   /// module needs, and then instantiate it.
-  WasmInstanceBuilder instantiate() {
-    return WasmInstanceBuilder(this);
-  }
+  WasmInstanceBuilder instantiate() => WasmInstanceBuilder(this);
 
   /// Create a new memory with the given number of initial pages, and optional
   /// maximum number of pages.
-  WasmMemory createMemory(int pages, [int? maxPages]) {
-    return WasmMemory._create(_store, pages, maxPages);
-  }
+  WasmMemory createMemory(int pages, [int? maxPages]) =>
+      WasmMemory._create(_store, pages, maxPages);
 
   /// Returns a description of all of the module's imports and exports, for
   /// debugging.
@@ -52,8 +49,11 @@
   }
 }
 
-Pointer<WasmerTrap> _wasmFnImportTrampoline(Pointer<_WasmFnImport> imp,
-    Pointer<WasmerValVec> args, Pointer<WasmerValVec> results) {
+Pointer<WasmerTrap> _wasmFnImportTrampoline(
+  Pointer<_WasmFnImport> imp,
+  Pointer<WasmerValVec> args,
+  Pointer<WasmerValVec> results,
+) {
   try {
     _WasmFnImport._call(imp, args, results);
   } catch (exception) {
@@ -68,12 +68,16 @@
 }
 
 final _wasmFnImportTrampolineNative = Pointer.fromFunction<
-    Pointer<WasmerTrap> Function(Pointer<_WasmFnImport>, Pointer<WasmerValVec>,
-        Pointer<WasmerValVec>)>(_wasmFnImportTrampoline);
+    Pointer<WasmerTrap> Function(
+  Pointer<_WasmFnImport>,
+  Pointer<WasmerValVec>,
+  Pointer<WasmerValVec>,
+)>(_wasmFnImportTrampoline);
 final _wasmFnImportToFn = <int, Function>{};
 final _wasmFnImportFinalizerNative =
     Pointer.fromFunction<Void Function(Pointer<_WasmFnImport>)>(
-        _wasmFnImportFinalizer);
+  _wasmFnImportFinalizer,
+);
 
 class _WasmFnImport extends Struct {
   @Int32()
@@ -81,30 +85,34 @@
 
   external Pointer<WasmerStore> store;
 
-  static void _call(Pointer<_WasmFnImport> imp, Pointer<WasmerValVec> rawArgs,
-      Pointer<WasmerValVec> rawResult) {
+  static void _call(
+    Pointer<_WasmFnImport> imp,
+    Pointer<WasmerValVec> rawArgs,
+    Pointer<WasmerValVec> rawResult,
+  ) {
     var fn = _wasmFnImportToFn[imp.address] as Function;
     var args = [];
     for (var i = 0; i < rawArgs.ref.length; ++i) {
       args.add(rawArgs.ref.data[i].toDynamic);
     }
     assert(
-        rawResult.ref.length == 1 || imp.ref.returnType == WasmerValKindVoid);
+      rawResult.ref.length == 1 || imp.ref.returnType == WasmerValKindVoid,
+    );
     var result = Function.apply(fn, args);
     if (imp.ref.returnType != WasmerValKindVoid) {
       rawResult.ref.data[0].kind = imp.ref.returnType;
       switch (imp.ref.returnType) {
         case WasmerValKindI32:
-          rawResult.ref.data[0].i32 = result;
+          rawResult.ref.data[0].i32 = result as int;
           break;
         case WasmerValKindI64:
-          rawResult.ref.data[0].i64 = result;
+          rawResult.ref.data[0].i64 = result as int;
           break;
         case WasmerValKindF32:
-          rawResult.ref.data[0].f32 = result;
+          rawResult.ref.data[0].f32 = result as int;
           break;
         case WasmerValKindF64:
-          rawResult.ref.data[0].f64 = result;
+          rawResult.ref.data[0].f64 = result as int;
           break;
       }
     }
@@ -135,11 +143,11 @@
   }
 
   int _getIndex(String moduleName, String name) {
-    var index = _importIndex['${moduleName}::${name}'];
+    var index = _importIndex['$moduleName::$name'];
     if (index == null) {
-      throw Exception('Import not found: ${moduleName}::${name}');
+      throw Exception('Import not found: $moduleName::$name');
     } else if (_imports.ref.data[index] != nullptr) {
-      throw Exception('Import already filled: ${moduleName}::${name}');
+      throw Exception('Import already filled: $moduleName::$name');
     } else {
       return index;
     }
@@ -147,7 +155,10 @@
 
   /// Add a WasmMemory to the imports.
   WasmInstanceBuilder addMemory(
-      String moduleName, String name, WasmMemory memory) {
+    String moduleName,
+    String name,
+    WasmMemory memory,
+  ) {
     var index = _getIndex(moduleName, name);
     var imp = _importDescs[index];
     if (imp.kind != WasmerExternKindMemory) {
@@ -173,19 +184,22 @@
     wasmFnImport.ref.store = _module._store;
     _wasmFnImportToFn[wasmFnImport.address] = fn;
     var fnImp = runtime.newFunc(
-        _importOwner,
-        _module._store,
-        imp.funcType,
-        _wasmFnImportTrampolineNative,
-        wasmFnImport,
-        _wasmFnImportFinalizerNative);
+      _importOwner,
+      _module._store,
+      imp.funcType,
+      _wasmFnImportTrampolineNative,
+      wasmFnImport,
+      _wasmFnImportFinalizerNative,
+    );
     _imports.ref.data[index] = runtime.functionToExtern(fnImp);
     return this;
   }
 
   /// Enable WASI and add the default WASI imports.
-  WasmInstanceBuilder enableWasi(
-      {bool captureStdout = false, bool captureStderr = false}) {
+  WasmInstanceBuilder enableWasi({
+    bool captureStdout = false,
+    bool captureStderr = false,
+  }) {
     if (_wasiEnv != nullptr) {
       throw Exception('WASI is already enabled.');
     }
@@ -205,7 +219,7 @@
         throw Exception('Missing import: ${_importDescs[i]}');
       }
     }
-    return WasmInstance(_module, _imports, _wasiEnv, _importOwner);
+    return WasmInstance(_module, _imports, _wasiEnv);
   }
 }
 
@@ -218,10 +232,12 @@
   Stream<List<int>>? _stdout;
   Stream<List<int>>? _stderr;
   final Map<String, WasmFunction> _functions = {};
-  final _WasmImportOwner _importOwner;
 
-  WasmInstance(this._module, Pointer<WasmerExternVec> imports, this._wasiEnv,
-      this._importOwner) {
+  WasmInstance(
+    this._module,
+    Pointer<WasmerExternVec> imports,
+    this._wasiEnv,
+  ) {
     var runtime = WasmRuntime();
     _instance =
         runtime.instantiate(this, _module._store, _module._module, imports);
@@ -236,7 +252,11 @@
         var f = runtime.externToFunction(e);
         var ft = exportDescs[i].funcType;
         _functions[name] = WasmFunction(
-            name, f, runtime.getArgTypes(ft), runtime.getReturnType(ft));
+          name,
+          f,
+          runtime.getArgTypes(ft),
+          runtime.getReturnType(ft),
+        );
       } else if (kind == WasmerExternKindMemory) {
         // WASM currently allows only one memory per module.
         var mem = runtime.externToMemory(e);
@@ -250,9 +270,7 @@
 
   /// Searches the instantiated module for the given function. Returns null if
   /// it is not found.
-  dynamic lookupFunction(String name) {
-    return _functions[name];
-  }
+  dynamic lookupFunction(String name) => _functions[name];
 
   /// Returns the memory exported from this instance.
   WasmMemory get memory {
@@ -301,9 +319,7 @@
   static const int kPageSizeInBytes = 64 * 1024;
 
   /// Returns the length of the memory in pages.
-  int get lengthInPages {
-    return WasmRuntime().memoryLength(_mem);
-  }
+  int get lengthInPages => WasmRuntime().memoryLength(_mem);
 
   /// Returns the length of the memory in bytes.
   int get lengthInBytes => _view.lengthInBytes;
@@ -321,8 +337,7 @@
 
   /// Grow the memory by deltaPages.
   void grow(int deltaPages) {
-    var runtime = WasmRuntime();
-    runtime.growMemory(_mem, deltaPages);
+    var runtime = WasmRuntime()..growMemory(_mem, deltaPages);
     _view = runtime.memoryView(_mem);
   }
 }
diff --git a/pkg/wasm/lib/src/runtime.dart b/pkg/wasm/lib/src/runtime.dart
index dbdb986..40e892b 100644
--- a/pkg/wasm/lib/src/runtime.dart
+++ b/pkg/wasm/lib/src/runtime.dart
@@ -2,23 +2,24 @@
 // 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 file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the following command
-// "generate_ffi_boilerplate.py".
-
 import 'dart:async';
 import 'dart:convert';
 import 'dart:ffi';
 import 'dart:io';
 import 'dart:typed_data';
+
 import 'package:ffi/ffi.dart';
+
 import 'wasmer_api.dart';
 
+part 'runtime.g.dart';
+
 class WasmImportDescriptor {
   int kind;
   String moduleName;
   String name;
   Pointer<WasmerFunctype> funcType;
+
   WasmImportDescriptor(this.kind, this.moduleName, this.name, this.funcType);
 
   @override
@@ -26,11 +27,14 @@
     var kindName = wasmerExternKindName(kind);
     if (kind == WasmerExternKindFunction) {
       var runtime = WasmRuntime();
-      var sig = WasmRuntime.getSignatureString('${moduleName}::${name}',
-          runtime.getArgTypes(funcType), runtime.getReturnType(funcType));
+      var sig = WasmRuntime.getSignatureString(
+        '$moduleName::$name',
+        runtime.getArgTypes(funcType),
+        runtime.getReturnType(funcType),
+      );
       return '$kindName: $sig';
     } else {
-      return '$kindName: ${moduleName}::${name}';
+      return '$kindName: $moduleName::$name';
     }
   }
 }
@@ -39,6 +43,7 @@
   int kind;
   String name;
   Pointer<WasmerFunctype> funcType;
+
   WasmExportDescriptor(this.kind, this.name, this.funcType);
 
   @override
@@ -47,665 +52,35 @@
     if (kind == WasmerExternKindFunction) {
       var runtime = WasmRuntime();
       var sig = WasmRuntime.getSignatureString(
-          name, runtime.getArgTypes(funcType), runtime.getReturnType(funcType));
+        name,
+        runtime.getArgTypes(funcType),
+        runtime.getReturnType(funcType),
+      );
       return '$kindName: $sig';
     } else {
-      return '$kindName: ${name}';
+      return '$kindName: $name';
     }
   }
 }
 
 class _WasmTrapsEntry {
-  dynamic exception;
+  Object exception;
+
   _WasmTrapsEntry(this.exception);
 }
 
-class WasmRuntime {
-  static WasmRuntime? _inst;
-
-  DynamicLibrary _lib;
-  late Pointer<WasmerEngine> _engine;
-  Map<int, _WasmTrapsEntry> traps = {};
-  late WasmerDartInitializeApiDLFn _Dart_InitializeApiDL;
-  late WasmerSetFinalizerForEngineFn _set_finalizer_for_engine;
-  late WasmerSetFinalizerForFuncFn _set_finalizer_for_func;
-  late WasmerSetFinalizerForInstanceFn _set_finalizer_for_instance;
-  late WasmerSetFinalizerForMemoryFn _set_finalizer_for_memory;
-  late WasmerSetFinalizerForMemorytypeFn _set_finalizer_for_memorytype;
-  late WasmerSetFinalizerForModuleFn _set_finalizer_for_module;
-  late WasmerSetFinalizerForStoreFn _set_finalizer_for_store;
-  late WasmerSetFinalizerForTrapFn _set_finalizer_for_trap;
-  late WasmerWasiConfigInheritStderrFn _wasi_config_inherit_stderr;
-  late WasmerWasiConfigInheritStdoutFn _wasi_config_inherit_stdout;
-  late WasmerWasiConfigNewFn _wasi_config_new;
-  late WasmerWasiEnvDeleteFn _wasi_env_delete;
-  late WasmerWasiEnvNewFn _wasi_env_new;
-  late WasmerWasiEnvReadStderrFn _wasi_env_read_stderr;
-  late WasmerWasiEnvReadStdoutFn _wasi_env_read_stdout;
-  late WasmerWasiEnvSetMemoryFn _wasi_env_set_memory;
-  late WasmerWasiGetImportsFn _wasi_get_imports;
-  late WasmerByteVecDeleteFn _byte_vec_delete;
-  late WasmerByteVecNewFn _byte_vec_new;
-  late WasmerByteVecNewEmptyFn _byte_vec_new_empty;
-  late WasmerByteVecNewUninitializedFn _byte_vec_new_uninitialized;
-  late WasmerEngineDeleteFn _engine_delete;
-  late WasmerEngineNewFn _engine_new;
-  late WasmerExporttypeNameFn _exporttype_name;
-  late WasmerExporttypeTypeFn _exporttype_type;
-  late WasmerExporttypeVecDeleteFn _exporttype_vec_delete;
-  late WasmerExporttypeVecNewFn _exporttype_vec_new;
-  late WasmerExporttypeVecNewEmptyFn _exporttype_vec_new_empty;
-  late WasmerExporttypeVecNewUninitializedFn _exporttype_vec_new_uninitialized;
-  late WasmerExternAsFuncFn _extern_as_func;
-  late WasmerExternAsMemoryFn _extern_as_memory;
-  late WasmerExternDeleteFn _extern_delete;
-  late WasmerExternKindFn _extern_kind;
-  late WasmerExternVecDeleteFn _extern_vec_delete;
-  late WasmerExternVecNewFn _extern_vec_new;
-  late WasmerExternVecNewEmptyFn _extern_vec_new_empty;
-  late WasmerExternVecNewUninitializedFn _extern_vec_new_uninitialized;
-  late WasmerExterntypeAsFunctypeFn _externtype_as_functype;
-  late WasmerExterntypeDeleteFn _externtype_delete;
-  late WasmerExterntypeKindFn _externtype_kind;
-  late WasmerFuncAsExternFn _func_as_extern;
-  late WasmerFuncCallFn _func_call;
-  late WasmerFuncDeleteFn _func_delete;
-  late WasmerFuncNewWithEnvFn _func_new_with_env;
-  late WasmerFunctypeDeleteFn _functype_delete;
-  late WasmerFunctypeParamsFn _functype_params;
-  late WasmerFunctypeResultsFn _functype_results;
-  late WasmerImporttypeModuleFn _importtype_module;
-  late WasmerImporttypeNameFn _importtype_name;
-  late WasmerImporttypeTypeFn _importtype_type;
-  late WasmerImporttypeVecDeleteFn _importtype_vec_delete;
-  late WasmerImporttypeVecNewFn _importtype_vec_new;
-  late WasmerImporttypeVecNewEmptyFn _importtype_vec_new_empty;
-  late WasmerImporttypeVecNewUninitializedFn _importtype_vec_new_uninitialized;
-  late WasmerInstanceDeleteFn _instance_delete;
-  late WasmerInstanceExportsFn _instance_exports;
-  late WasmerInstanceNewFn _instance_new;
-  late WasmerMemoryAsExternFn _memory_as_extern;
-  late WasmerMemoryDataFn _memory_data;
-  late WasmerMemoryDataSizeFn _memory_data_size;
-  late WasmerMemoryDeleteFn _memory_delete;
-  late WasmerMemoryGrowFn _memory_grow;
-  late WasmerMemoryNewFn _memory_new;
-  late WasmerMemorySizeFn _memory_size;
-  late WasmerMemorytypeDeleteFn _memorytype_delete;
-  late WasmerMemorytypeNewFn _memorytype_new;
-  late WasmerModuleDeleteFn _module_delete;
-  late WasmerModuleExportsFn _module_exports;
-  late WasmerModuleImportsFn _module_imports;
-  late WasmerModuleNewFn _module_new;
-  late WasmerStoreDeleteFn _store_delete;
-  late WasmerStoreNewFn _store_new;
-  late WasmerTrapDeleteFn _trap_delete;
-  late WasmerTrapMessageFn _trap_message;
-  late WasmerTrapNewFn _trap_new;
-  late WasmerValtypeDeleteFn _valtype_delete;
-  late WasmerValtypeKindFn _valtype_kind;
-  late WasmerValtypeVecDeleteFn _valtype_vec_delete;
-  late WasmerValtypeVecNewFn _valtype_vec_new;
-  late WasmerValtypeVecNewEmptyFn _valtype_vec_new_empty;
-  late WasmerValtypeVecNewUninitializedFn _valtype_vec_new_uninitialized;
-  late WasmerWasmerLastErrorLengthFn _wasmer_last_error_length;
-  late WasmerWasmerLastErrorMessageFn _wasmer_last_error_message;
-
-  factory WasmRuntime() {
-    return _inst ??= WasmRuntime._init();
-  }
-
-  static String _getLibName() {
-    if (Platform.isMacOS) return 'libwasmer.dylib';
-    if (Platform.isLinux) return 'libwasmer.so';
-    // TODO(dartbug.com/37882): Support more platforms.
-    throw Exception('Wasm not currently supported on this platform');
-  }
-
-  static String? _getLibPathFrom(Uri root) {
-    // The dynamic library created by pub run wasm:setup is located relative to
-    // the package_config.json file, so walk up from the script directory until
-    // we find it.
-    do {
-      if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
-          .existsSync()) {
-        return root.resolve('.dart_tool/wasm/' + _getLibName()).path;
-      }
-    } while (root != (root = root.resolve('..')));
-    return null;
-  }
-
-  static String _getLibPath() {
-    var path = _getLibPathFrom(Platform.script.resolve('./'));
-    if (path != null) return path;
-    path = _getLibPathFrom(Directory.current.uri);
-    if (path != null) return path;
-    throw Exception('Wasm library not found. Did you `pub run wasm:setup`?');
-  }
-
-  WasmRuntime._init() : _lib = DynamicLibrary.open(_getLibPath()) {
-    _Dart_InitializeApiDL = _lib.lookupFunction<
-        NativeWasmerDartInitializeApiDLFn,
-        WasmerDartInitializeApiDLFn>('Dart_InitializeApiDL');
-    _set_finalizer_for_engine = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForEngineFn,
-        WasmerSetFinalizerForEngineFn>('set_finalizer_for_engine');
-    _set_finalizer_for_func = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForFuncFn,
-        WasmerSetFinalizerForFuncFn>('set_finalizer_for_func');
-    _set_finalizer_for_instance = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForInstanceFn,
-        WasmerSetFinalizerForInstanceFn>('set_finalizer_for_instance');
-    _set_finalizer_for_memory = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForMemoryFn,
-        WasmerSetFinalizerForMemoryFn>('set_finalizer_for_memory');
-    _set_finalizer_for_memorytype = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForMemorytypeFn,
-        WasmerSetFinalizerForMemorytypeFn>('set_finalizer_for_memorytype');
-    _set_finalizer_for_module = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForModuleFn,
-        WasmerSetFinalizerForModuleFn>('set_finalizer_for_module');
-    _set_finalizer_for_store = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForStoreFn,
-        WasmerSetFinalizerForStoreFn>('set_finalizer_for_store');
-    _set_finalizer_for_trap = _lib.lookupFunction<
-        NativeWasmerSetFinalizerForTrapFn,
-        WasmerSetFinalizerForTrapFn>('set_finalizer_for_trap');
-    _wasi_config_inherit_stderr = _lib.lookupFunction<
-        NativeWasmerWasiConfigInheritStderrFn,
-        WasmerWasiConfigInheritStderrFn>('wasi_config_inherit_stderr');
-    _wasi_config_inherit_stdout = _lib.lookupFunction<
-        NativeWasmerWasiConfigInheritStdoutFn,
-        WasmerWasiConfigInheritStdoutFn>('wasi_config_inherit_stdout');
-    _wasi_config_new =
-        _lib.lookupFunction<NativeWasmerWasiConfigNewFn, WasmerWasiConfigNewFn>(
-            'wasi_config_new');
-    _wasi_env_delete =
-        _lib.lookupFunction<NativeWasmerWasiEnvDeleteFn, WasmerWasiEnvDeleteFn>(
-            'wasi_env_delete');
-    _wasi_env_new =
-        _lib.lookupFunction<NativeWasmerWasiEnvNewFn, WasmerWasiEnvNewFn>(
-            'wasi_env_new');
-    _wasi_env_read_stderr = _lib.lookupFunction<NativeWasmerWasiEnvReadStderrFn,
-        WasmerWasiEnvReadStderrFn>('wasi_env_read_stderr');
-    _wasi_env_read_stdout = _lib.lookupFunction<NativeWasmerWasiEnvReadStdoutFn,
-        WasmerWasiEnvReadStdoutFn>('wasi_env_read_stdout');
-    _wasi_env_set_memory = _lib.lookupFunction<NativeWasmerWasiEnvSetMemoryFn,
-        WasmerWasiEnvSetMemoryFn>('wasi_env_set_memory');
-    _wasi_get_imports = _lib.lookupFunction<NativeWasmerWasiGetImportsFn,
-        WasmerWasiGetImportsFn>('wasi_get_imports');
-    _byte_vec_delete =
-        _lib.lookupFunction<NativeWasmerByteVecDeleteFn, WasmerByteVecDeleteFn>(
-            'wasm_byte_vec_delete');
-    _byte_vec_new =
-        _lib.lookupFunction<NativeWasmerByteVecNewFn, WasmerByteVecNewFn>(
-            'wasm_byte_vec_new');
-    _byte_vec_new_empty = _lib.lookupFunction<NativeWasmerByteVecNewEmptyFn,
-        WasmerByteVecNewEmptyFn>('wasm_byte_vec_new_empty');
-    _byte_vec_new_uninitialized = _lib.lookupFunction<
-        NativeWasmerByteVecNewUninitializedFn,
-        WasmerByteVecNewUninitializedFn>('wasm_byte_vec_new_uninitialized');
-    _engine_delete =
-        _lib.lookupFunction<NativeWasmerEngineDeleteFn, WasmerEngineDeleteFn>(
-            'wasm_engine_delete');
-    _engine_new =
-        _lib.lookupFunction<NativeWasmerEngineNewFn, WasmerEngineNewFn>(
-            'wasm_engine_new');
-    _exporttype_name = _lib.lookupFunction<NativeWasmerExporttypeNameFn,
-        WasmerExporttypeNameFn>('wasm_exporttype_name');
-    _exporttype_type = _lib.lookupFunction<NativeWasmerExporttypeTypeFn,
-        WasmerExporttypeTypeFn>('wasm_exporttype_type');
-    _exporttype_vec_delete = _lib.lookupFunction<
-        NativeWasmerExporttypeVecDeleteFn,
-        WasmerExporttypeVecDeleteFn>('wasm_exporttype_vec_delete');
-    _exporttype_vec_new = _lib.lookupFunction<NativeWasmerExporttypeVecNewFn,
-        WasmerExporttypeVecNewFn>('wasm_exporttype_vec_new');
-    _exporttype_vec_new_empty = _lib.lookupFunction<
-        NativeWasmerExporttypeVecNewEmptyFn,
-        WasmerExporttypeVecNewEmptyFn>('wasm_exporttype_vec_new_empty');
-    _exporttype_vec_new_uninitialized = _lib.lookupFunction<
-            NativeWasmerExporttypeVecNewUninitializedFn,
-            WasmerExporttypeVecNewUninitializedFn>(
-        'wasm_exporttype_vec_new_uninitialized');
-    _extern_as_func =
-        _lib.lookupFunction<NativeWasmerExternAsFuncFn, WasmerExternAsFuncFn>(
-            'wasm_extern_as_func');
-    _extern_as_memory = _lib.lookupFunction<NativeWasmerExternAsMemoryFn,
-        WasmerExternAsMemoryFn>('wasm_extern_as_memory');
-    _extern_delete =
-        _lib.lookupFunction<NativeWasmerExternDeleteFn, WasmerExternDeleteFn>(
-            'wasm_extern_delete');
-    _extern_kind =
-        _lib.lookupFunction<NativeWasmerExternKindFn, WasmerExternKindFn>(
-            'wasm_extern_kind');
-    _extern_vec_delete = _lib.lookupFunction<NativeWasmerExternVecDeleteFn,
-        WasmerExternVecDeleteFn>('wasm_extern_vec_delete');
-    _extern_vec_new =
-        _lib.lookupFunction<NativeWasmerExternVecNewFn, WasmerExternVecNewFn>(
-            'wasm_extern_vec_new');
-    _extern_vec_new_empty = _lib.lookupFunction<NativeWasmerExternVecNewEmptyFn,
-        WasmerExternVecNewEmptyFn>('wasm_extern_vec_new_empty');
-    _extern_vec_new_uninitialized = _lib.lookupFunction<
-        NativeWasmerExternVecNewUninitializedFn,
-        WasmerExternVecNewUninitializedFn>('wasm_extern_vec_new_uninitialized');
-    _externtype_as_functype = _lib.lookupFunction<
-        NativeWasmerExterntypeAsFunctypeFn,
-        WasmerExterntypeAsFunctypeFn>('wasm_externtype_as_functype');
-    _externtype_delete = _lib.lookupFunction<NativeWasmerExterntypeDeleteFn,
-        WasmerExterntypeDeleteFn>('wasm_externtype_delete');
-    _externtype_kind = _lib.lookupFunction<NativeWasmerExterntypeKindFn,
-        WasmerExterntypeKindFn>('wasm_externtype_kind');
-    _func_as_extern =
-        _lib.lookupFunction<NativeWasmerFuncAsExternFn, WasmerFuncAsExternFn>(
-            'wasm_func_as_extern');
-    _func_call = _lib.lookupFunction<NativeWasmerFuncCallFn, WasmerFuncCallFn>(
-        'wasm_func_call');
-    _func_delete =
-        _lib.lookupFunction<NativeWasmerFuncDeleteFn, WasmerFuncDeleteFn>(
-            'wasm_func_delete');
-    _func_new_with_env = _lib.lookupFunction<NativeWasmerFuncNewWithEnvFn,
-        WasmerFuncNewWithEnvFn>('wasm_func_new_with_env');
-    _functype_delete = _lib.lookupFunction<NativeWasmerFunctypeDeleteFn,
-        WasmerFunctypeDeleteFn>('wasm_functype_delete');
-    _functype_params = _lib.lookupFunction<NativeWasmerFunctypeParamsFn,
-        WasmerFunctypeParamsFn>('wasm_functype_params');
-    _functype_results = _lib.lookupFunction<NativeWasmerFunctypeResultsFn,
-        WasmerFunctypeResultsFn>('wasm_functype_results');
-    _importtype_module = _lib.lookupFunction<NativeWasmerImporttypeModuleFn,
-        WasmerImporttypeModuleFn>('wasm_importtype_module');
-    _importtype_name = _lib.lookupFunction<NativeWasmerImporttypeNameFn,
-        WasmerImporttypeNameFn>('wasm_importtype_name');
-    _importtype_type = _lib.lookupFunction<NativeWasmerImporttypeTypeFn,
-        WasmerImporttypeTypeFn>('wasm_importtype_type');
-    _importtype_vec_delete = _lib.lookupFunction<
-        NativeWasmerImporttypeVecDeleteFn,
-        WasmerImporttypeVecDeleteFn>('wasm_importtype_vec_delete');
-    _importtype_vec_new = _lib.lookupFunction<NativeWasmerImporttypeVecNewFn,
-        WasmerImporttypeVecNewFn>('wasm_importtype_vec_new');
-    _importtype_vec_new_empty = _lib.lookupFunction<
-        NativeWasmerImporttypeVecNewEmptyFn,
-        WasmerImporttypeVecNewEmptyFn>('wasm_importtype_vec_new_empty');
-    _importtype_vec_new_uninitialized = _lib.lookupFunction<
-            NativeWasmerImporttypeVecNewUninitializedFn,
-            WasmerImporttypeVecNewUninitializedFn>(
-        'wasm_importtype_vec_new_uninitialized');
-    _instance_delete = _lib.lookupFunction<NativeWasmerInstanceDeleteFn,
-        WasmerInstanceDeleteFn>('wasm_instance_delete');
-    _instance_exports = _lib.lookupFunction<NativeWasmerInstanceExportsFn,
-        WasmerInstanceExportsFn>('wasm_instance_exports');
-    _instance_new =
-        _lib.lookupFunction<NativeWasmerInstanceNewFn, WasmerInstanceNewFn>(
-            'wasm_instance_new');
-    _memory_as_extern = _lib.lookupFunction<NativeWasmerMemoryAsExternFn,
-        WasmerMemoryAsExternFn>('wasm_memory_as_extern');
-    _memory_data =
-        _lib.lookupFunction<NativeWasmerMemoryDataFn, WasmerMemoryDataFn>(
-            'wasm_memory_data');
-    _memory_data_size = _lib.lookupFunction<NativeWasmerMemoryDataSizeFn,
-        WasmerMemoryDataSizeFn>('wasm_memory_data_size');
-    _memory_delete =
-        _lib.lookupFunction<NativeWasmerMemoryDeleteFn, WasmerMemoryDeleteFn>(
-            'wasm_memory_delete');
-    _memory_grow =
-        _lib.lookupFunction<NativeWasmerMemoryGrowFn, WasmerMemoryGrowFn>(
-            'wasm_memory_grow');
-    _memory_new =
-        _lib.lookupFunction<NativeWasmerMemoryNewFn, WasmerMemoryNewFn>(
-            'wasm_memory_new');
-    _memory_size =
-        _lib.lookupFunction<NativeWasmerMemorySizeFn, WasmerMemorySizeFn>(
-            'wasm_memory_size');
-    _memorytype_delete = _lib.lookupFunction<NativeWasmerMemorytypeDeleteFn,
-        WasmerMemorytypeDeleteFn>('wasm_memorytype_delete');
-    _memorytype_new =
-        _lib.lookupFunction<NativeWasmerMemorytypeNewFn, WasmerMemorytypeNewFn>(
-            'wasm_memorytype_new');
-    _module_delete =
-        _lib.lookupFunction<NativeWasmerModuleDeleteFn, WasmerModuleDeleteFn>(
-            'wasm_module_delete');
-    _module_exports =
-        _lib.lookupFunction<NativeWasmerModuleExportsFn, WasmerModuleExportsFn>(
-            'wasm_module_exports');
-    _module_imports =
-        _lib.lookupFunction<NativeWasmerModuleImportsFn, WasmerModuleImportsFn>(
-            'wasm_module_imports');
-    _module_new =
-        _lib.lookupFunction<NativeWasmerModuleNewFn, WasmerModuleNewFn>(
-            'wasm_module_new');
-    _store_delete =
-        _lib.lookupFunction<NativeWasmerStoreDeleteFn, WasmerStoreDeleteFn>(
-            'wasm_store_delete');
-    _store_new = _lib.lookupFunction<NativeWasmerStoreNewFn, WasmerStoreNewFn>(
-        'wasm_store_new');
-    _trap_delete =
-        _lib.lookupFunction<NativeWasmerTrapDeleteFn, WasmerTrapDeleteFn>(
-            'wasm_trap_delete');
-    _trap_message =
-        _lib.lookupFunction<NativeWasmerTrapMessageFn, WasmerTrapMessageFn>(
-            'wasm_trap_message');
-    _trap_new = _lib.lookupFunction<NativeWasmerTrapNewFn, WasmerTrapNewFn>(
-        'wasm_trap_new');
-    _valtype_delete =
-        _lib.lookupFunction<NativeWasmerValtypeDeleteFn, WasmerValtypeDeleteFn>(
-            'wasm_valtype_delete');
-    _valtype_kind =
-        _lib.lookupFunction<NativeWasmerValtypeKindFn, WasmerValtypeKindFn>(
-            'wasm_valtype_kind');
-    _valtype_vec_delete = _lib.lookupFunction<NativeWasmerValtypeVecDeleteFn,
-        WasmerValtypeVecDeleteFn>('wasm_valtype_vec_delete');
-    _valtype_vec_new =
-        _lib.lookupFunction<NativeWasmerValtypeVecNewFn, WasmerValtypeVecNewFn>(
-            'wasm_valtype_vec_new');
-    _valtype_vec_new_empty = _lib.lookupFunction<
-        NativeWasmerValtypeVecNewEmptyFn,
-        WasmerValtypeVecNewEmptyFn>('wasm_valtype_vec_new_empty');
-    _valtype_vec_new_uninitialized = _lib.lookupFunction<
-            NativeWasmerValtypeVecNewUninitializedFn,
-            WasmerValtypeVecNewUninitializedFn>(
-        'wasm_valtype_vec_new_uninitialized');
-    _wasmer_last_error_length = _lib.lookupFunction<
-        NativeWasmerWasmerLastErrorLengthFn,
-        WasmerWasmerLastErrorLengthFn>('wasmer_last_error_length');
-    _wasmer_last_error_message = _lib.lookupFunction<
-        NativeWasmerWasmerLastErrorMessageFn,
-        WasmerWasmerLastErrorMessageFn>('wasmer_last_error_message');
-
-    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
-      throw Exception('Failed to initialize Dart API');
-    }
-    _engine = _engine_new();
-    _checkNotEqual(_engine, nullptr, 'Failed to initialize Wasm engine.');
-    _set_finalizer_for_engine(this, _engine);
-  }
-
-  Pointer<WasmerStore> newStore(Object owner) {
-    var store = _checkNotEqual(
-        _store_new(_engine), nullptr, 'Failed to create Wasm store.');
-    _set_finalizer_for_store(owner, store);
-    return store;
-  }
-
-  Pointer<WasmerModule> compile(
-      Object owner, Pointer<WasmerStore> store, Uint8List data) {
-    var dataPtr = calloc<Uint8>(data.length);
-    for (var i = 0; i < data.length; ++i) {
-      dataPtr[i] = data[i];
-    }
-    var dataVec = calloc<WasmerByteVec>();
-    dataVec.ref.data = dataPtr;
-    dataVec.ref.length = data.length;
-
-    var modulePtr = _module_new(store, dataVec);
-
-    calloc.free(dataPtr);
-    calloc.free(dataVec);
-
-    _checkNotEqual(modulePtr, nullptr, 'Wasm module compile failed.');
-    _set_finalizer_for_module(owner, modulePtr);
-    return modulePtr;
-  }
-
-  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
-    var exportsVec = calloc<WasmerExporttypeVec>();
-    _module_exports(module, exportsVec);
-    var exps = <WasmExportDescriptor>[];
-    for (var i = 0; i < exportsVec.ref.length; ++i) {
-      var exp = exportsVec.ref.data[i];
-      var extern = _exporttype_type(exp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      exps.add(WasmExportDescriptor(
-          kind, _exporttype_name(exp).ref.toString(), fnType));
-    }
-    calloc.free(exportsVec);
-    return exps;
-  }
-
-  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
-    var importsVec = calloc<WasmerImporttypeVec>();
-    _module_imports(module, importsVec);
-    var imps = <WasmImportDescriptor>[];
-    for (var i = 0; i < importsVec.ref.length; ++i) {
-      var imp = importsVec.ref.data[i];
-      var extern = _importtype_type(imp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      imps.add(WasmImportDescriptor(
-          kind,
-          _importtype_module(imp).ref.toString(),
-          _importtype_name(imp).ref.toString(),
-          fnType));
-    }
-    calloc.free(importsVec);
-    return imps;
-  }
-
-  void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
-    if (trap != nullptr) {
-      // There are 2 kinds of trap, and their memory is managed differently.
-      // Traps created in the newTrap method below are stored in the traps map
-      // with a corresponding exception, and their memory is managed using a
-      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
-      // code, and in that case we delete them in this function.
-      var entry = traps[trap.address];
-      if (entry != null) {
-        traps.remove(entry);
-        throw entry.exception;
-      } else {
-        var trapMessage = calloc<WasmerByteVec>();
-        _trap_message(trap, trapMessage);
-        var message = 'Wasm trap when calling $source: ${trapMessage.ref}';
-        _byte_vec_delete(trapMessage);
-        calloc.free(trapMessage);
-        _trap_delete(trap);
-        throw Exception(message);
-      }
-    }
-  }
-
-  Pointer<WasmerInstance> instantiate(Object owner, Pointer<WasmerStore> store,
-      Pointer<WasmerModule> module, Pointer<WasmerExternVec> imports) {
-    var trap = calloc<Pointer<WasmerTrap>>();
-    trap.value = nullptr;
-    var inst = _instance_new(store, module, imports, trap);
-    maybeThrowTrap(trap.value, 'module initialization function');
-    calloc.free(trap);
-    _checkNotEqual(inst, nullptr, 'Wasm module instantiation failed.');
-    _set_finalizer_for_instance(owner, inst);
-    return inst;
-  }
-
-  // Clean up the exports after use, with deleteExports.
-  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
-    var exports = calloc<WasmerExternVec>();
-    _instance_exports(instancePtr, exports);
-    return exports;
-  }
-
-  void deleteExports(Pointer<WasmerExternVec> exports) {
-    _extern_vec_delete(exports);
-    calloc.free(exports);
-  }
-
-  int externKind(Pointer<WasmerExtern> extern) {
-    return _extern_kind(extern);
-  }
-
-  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) {
-    return _extern_as_func(extern);
-  }
-
-  Pointer<WasmerExtern> functionToExtern(Pointer<WasmerFunc> func) {
-    return _func_as_extern(func);
-  }
-
-  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
-    var types = <int>[];
-    var args = _functype_params(funcType);
-    for (var i = 0; i < args.ref.length; ++i) {
-      types.add(_valtype_kind(args.ref.data[i]));
-    }
-    return types;
-  }
-
-  int getReturnType(Pointer<WasmerFunctype> funcType) {
-    var rets = _functype_results(funcType);
-    if (rets.ref.length == 0) {
-      return WasmerValKindVoid;
-    } else if (rets.ref.length > 1) {
-      throw Exception('Multiple return values are not supported');
-    }
-    return _valtype_kind(rets.ref.data[0]);
-  }
-
-  void call(Pointer<WasmerFunc> func, Pointer<WasmerValVec> args,
-      Pointer<WasmerValVec> results, String source) {
-    maybeThrowTrap(_func_call(func, args, results), source);
-  }
-
-  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) {
-    return _extern_as_memory(extern);
-  }
-
-  Pointer<WasmerExtern> memoryToExtern(Pointer<WasmerMemory> memory) {
-    return _memory_as_extern(memory);
-  }
-
-  Pointer<WasmerMemory> newMemory(
-      Object owner, Pointer<WasmerStore> store, int pages, int? maxPages) {
-    var limPtr = calloc<WasmerLimits>();
-    limPtr.ref.min = pages;
-    limPtr.ref.max = maxPages ?? wasm_limits_max_default;
-    var memType = _memorytype_new(limPtr);
-    calloc.free(limPtr);
-    _checkNotEqual(memType, nullptr, 'Failed to create memory type.');
-    _set_finalizer_for_memorytype(owner, memType);
-    var memory = _checkNotEqual(
-        _memory_new(store, memType), nullptr, 'Failed to create memory.');
-    _set_finalizer_for_memory(owner, memory);
-    return memory;
-  }
-
-  void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
-    _checkNotEqual(
-        _memory_grow(memory, deltaPages), 0, 'Failed to grow memory.');
-  }
-
-  int memoryLength(Pointer<WasmerMemory> memory) {
-    return _memory_size(memory);
-  }
-
-  Uint8List memoryView(Pointer<WasmerMemory> memory) {
-    return _memory_data(memory).asTypedList(_memory_data_size(memory));
-  }
-
-  Pointer<WasmerFunc> newFunc(
-      Object owner,
-      Pointer<WasmerStore> store,
-      Pointer<WasmerFunctype> funcType,
-      Pointer func,
-      Pointer env,
-      Pointer finalizer) {
-    var f = _func_new_with_env(
-        store, funcType, func.cast(), env.cast(), finalizer.cast());
-    _checkNotEqual(f, nullptr, 'Failed to create function.');
-    _set_finalizer_for_func(owner, f);
-    return f;
-  }
-
-  Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, dynamic exception) {
-    var msg = calloc<WasmerByteVec>();
-    msg.ref.data = calloc<Uint8>();
-    msg.ref.data[0] = 0;
-    msg.ref.length = 0;
-    var trap = _trap_new(store, msg);
-    calloc.free(msg.ref.data);
-    calloc.free(msg);
-    _checkNotEqual(trap, nullptr, 'Failed to create trap.');
-    var entry = _WasmTrapsEntry(exception);
-    _set_finalizer_for_trap(entry, trap);
-    traps[trap.address] = entry;
-    return trap;
-  }
-
-  Pointer<WasmerWasiConfig> newWasiConfig() {
-    var name = calloc<Uint8>();
-    name[0] = 0;
-    var config = _wasi_config_new(name);
-    calloc.free(name);
-    return _checkNotEqual(config, nullptr, 'Failed to create WASI config.');
-  }
-
-  void captureWasiStdout(Pointer<WasmerWasiConfig> config) {
-    _wasi_config_inherit_stdout(config);
-  }
-
-  void captureWasiStderr(Pointer<WasmerWasiConfig> config) {
-    _wasi_config_inherit_stderr(config);
-  }
-
-  Pointer<WasmerWasiEnv> newWasiEnv(Pointer<WasmerWasiConfig> config) {
-    return _checkNotEqual(
-        _wasi_env_new(config), nullptr, 'Failed to create WASI environment.');
-  }
-
-  void wasiEnvSetMemory(
-      Pointer<WasmerWasiEnv> env, Pointer<WasmerMemory> memory) {
-    _wasi_env_set_memory(env, memory);
-  }
-
-  void getWasiImports(Pointer<WasmerStore> store, Pointer<WasmerModule> mod,
-      Pointer<WasmerWasiEnv> env, Pointer<WasmerExternVec> imports) {
-    _checkNotEqual(_wasi_get_imports(store, mod, env, imports), 0,
-        'Failed to fill WASI imports.');
-  }
-
-  Stream<List<int>> getWasiStdoutStream(Pointer<WasmerWasiEnv> env) {
-    return Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stdout));
-  }
-
-  Stream<List<int>> getWasiStderrStream(Pointer<WasmerWasiEnv> env) {
-    return Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stderr));
-  }
-
-  String _getLastError() {
-    var length = _wasmer_last_error_length();
-    var buf = calloc<Uint8>(length);
-    _wasmer_last_error_message(buf, length);
-    var message = utf8.decode(buf.asTypedList(length));
-    calloc.free(buf);
-    return message;
-  }
-
-  T _checkNotEqual<T>(T x, T y, String errorMessage) {
-    if (x == y) {
-      throw Exception('$errorMessage\n${_getLastError()}');
-    }
-    return x;
-  }
-
-  static String getSignatureString(
-      String name, List<int> argTypes, int returnType) {
-    return '${wasmerValKindName(returnType)} $name'
-        "(${argTypes.map(wasmerValKindName).join(", ")})";
-  }
-}
-
 class _WasiStreamIterator implements Iterator<List<int>> {
-  static final int _bufferLength = 1024;
+  static const int _bufferLength = 1024;
   final Pointer<WasmerWasiEnv> _env;
   final Function _reader;
   final Pointer<Uint8> _buf = calloc<Uint8>(_bufferLength);
   int _length = 0;
+
   _WasiStreamIterator(this._env, this._reader);
 
   @override
   bool moveNext() {
-    _length = _reader(_env, _buf, _bufferLength);
+    _length = _reader(_env, _buf, _bufferLength) as int;
     return true;
   }
 
@@ -716,7 +91,37 @@
 class _WasiStreamIterable extends Iterable<List<int>> {
   final Pointer<WasmerWasiEnv> _env;
   final Function _reader;
+
   _WasiStreamIterable(this._env, this._reader);
+
   @override
   Iterator<List<int>> get iterator => _WasiStreamIterator(_env, _reader);
 }
+
+String _getLibName() {
+  if (Platform.isMacOS) return 'libwasmer.dylib';
+  if (Platform.isLinux) return 'libwasmer.so';
+  // TODO(dartbug.com/37882): Support more platforms.
+  throw Exception('Wasm not currently supported on this platform');
+}
+
+String? _getLibPathFrom(Uri root) {
+  // The dynamic library created by pub run wasm:setup is located relative to
+  // the package_config.json file, so walk up from the script directory until
+  // we find it.
+  do {
+    if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
+        .existsSync()) {
+      return root.resolve('.dart_tool/wasm/${_getLibName()}').path;
+    }
+  } while (root != (root = root.resolve('..')));
+  return null;
+}
+
+String _getLibPath() {
+  var path = _getLibPathFrom(Platform.script.resolve('./'));
+  if (path != null) return path;
+  path = _getLibPathFrom(Directory.current.uri);
+  if (path != null) return path;
+  throw Exception('Wasm library not found. Did you `pub run wasm:setup`?');
+}
diff --git a/pkg/wasm/lib/src/runtime.g.dart b/pkg/wasm/lib/src/runtime.g.dart
new file mode 100644
index 0000000..eb72930
--- /dev/null
+++ b/pkg/wasm/lib/src/runtime.g.dart
@@ -0,0 +1,773 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the following command
+// "generate_ffi_boilerplate.py".
+
+// ignore_for_file: cascade_invocations
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: unused_field
+
+part of 'runtime.dart';
+
+class WasmRuntime {
+  static WasmRuntime? _inst;
+
+  DynamicLibrary _lib;
+  late Pointer<WasmerEngine> _engine;
+  Map<int, _WasmTrapsEntry> traps = {};
+
+  late WasmerDartInitializeApiDLFn _Dart_InitializeApiDL;
+  late WasmerSetFinalizerForEngineFn _set_finalizer_for_engine;
+  late WasmerSetFinalizerForFuncFn _set_finalizer_for_func;
+  late WasmerSetFinalizerForInstanceFn _set_finalizer_for_instance;
+  late WasmerSetFinalizerForMemoryFn _set_finalizer_for_memory;
+  late WasmerSetFinalizerForMemorytypeFn _set_finalizer_for_memorytype;
+  late WasmerSetFinalizerForModuleFn _set_finalizer_for_module;
+  late WasmerSetFinalizerForStoreFn _set_finalizer_for_store;
+  late WasmerSetFinalizerForTrapFn _set_finalizer_for_trap;
+  late WasmerWasiConfigInheritStderrFn _wasi_config_inherit_stderr;
+  late WasmerWasiConfigInheritStdoutFn _wasi_config_inherit_stdout;
+  late WasmerWasiConfigNewFn _wasi_config_new;
+  late WasmerWasiEnvDeleteFn _wasi_env_delete;
+  late WasmerWasiEnvNewFn _wasi_env_new;
+  late WasmerWasiEnvReadStderrFn _wasi_env_read_stderr;
+  late WasmerWasiEnvReadStdoutFn _wasi_env_read_stdout;
+  late WasmerWasiEnvSetMemoryFn _wasi_env_set_memory;
+  late WasmerWasiGetImportsFn _wasi_get_imports;
+  late WasmerByteVecDeleteFn _byte_vec_delete;
+  late WasmerByteVecNewFn _byte_vec_new;
+  late WasmerByteVecNewEmptyFn _byte_vec_new_empty;
+  late WasmerByteVecNewUninitializedFn _byte_vec_new_uninitialized;
+  late WasmerEngineDeleteFn _engine_delete;
+  late WasmerEngineNewFn _engine_new;
+  late WasmerExporttypeNameFn _exporttype_name;
+  late WasmerExporttypeTypeFn _exporttype_type;
+  late WasmerExporttypeVecDeleteFn _exporttype_vec_delete;
+  late WasmerExporttypeVecNewFn _exporttype_vec_new;
+  late WasmerExporttypeVecNewEmptyFn _exporttype_vec_new_empty;
+  late WasmerExporttypeVecNewUninitializedFn _exporttype_vec_new_uninitialized;
+  late WasmerExternAsFuncFn _extern_as_func;
+  late WasmerExternAsMemoryFn _extern_as_memory;
+  late WasmerExternDeleteFn _extern_delete;
+  late WasmerExternKindFn _extern_kind;
+  late WasmerExternVecDeleteFn _extern_vec_delete;
+  late WasmerExternVecNewFn _extern_vec_new;
+  late WasmerExternVecNewEmptyFn _extern_vec_new_empty;
+  late WasmerExternVecNewUninitializedFn _extern_vec_new_uninitialized;
+  late WasmerExterntypeAsFunctypeFn _externtype_as_functype;
+  late WasmerExterntypeDeleteFn _externtype_delete;
+  late WasmerExterntypeKindFn _externtype_kind;
+  late WasmerFuncAsExternFn _func_as_extern;
+  late WasmerFuncCallFn _func_call;
+  late WasmerFuncDeleteFn _func_delete;
+  late WasmerFuncNewWithEnvFn _func_new_with_env;
+  late WasmerFunctypeDeleteFn _functype_delete;
+  late WasmerFunctypeParamsFn _functype_params;
+  late WasmerFunctypeResultsFn _functype_results;
+  late WasmerImporttypeModuleFn _importtype_module;
+  late WasmerImporttypeNameFn _importtype_name;
+  late WasmerImporttypeTypeFn _importtype_type;
+  late WasmerImporttypeVecDeleteFn _importtype_vec_delete;
+  late WasmerImporttypeVecNewFn _importtype_vec_new;
+  late WasmerImporttypeVecNewEmptyFn _importtype_vec_new_empty;
+  late WasmerImporttypeVecNewUninitializedFn _importtype_vec_new_uninitialized;
+  late WasmerInstanceDeleteFn _instance_delete;
+  late WasmerInstanceExportsFn _instance_exports;
+  late WasmerInstanceNewFn _instance_new;
+  late WasmerMemoryAsExternFn _memory_as_extern;
+  late WasmerMemoryDataFn _memory_data;
+  late WasmerMemoryDataSizeFn _memory_data_size;
+  late WasmerMemoryDeleteFn _memory_delete;
+  late WasmerMemoryGrowFn _memory_grow;
+  late WasmerMemoryNewFn _memory_new;
+  late WasmerMemorySizeFn _memory_size;
+  late WasmerMemorytypeDeleteFn _memorytype_delete;
+  late WasmerMemorytypeNewFn _memorytype_new;
+  late WasmerModuleDeleteFn _module_delete;
+  late WasmerModuleExportsFn _module_exports;
+  late WasmerModuleImportsFn _module_imports;
+  late WasmerModuleNewFn _module_new;
+  late WasmerStoreDeleteFn _store_delete;
+  late WasmerStoreNewFn _store_new;
+  late WasmerTrapDeleteFn _trap_delete;
+  late WasmerTrapMessageFn _trap_message;
+  late WasmerTrapNewFn _trap_new;
+  late WasmerValtypeDeleteFn _valtype_delete;
+  late WasmerValtypeKindFn _valtype_kind;
+  late WasmerValtypeVecDeleteFn _valtype_vec_delete;
+  late WasmerValtypeVecNewFn _valtype_vec_new;
+  late WasmerValtypeVecNewEmptyFn _valtype_vec_new_empty;
+  late WasmerValtypeVecNewUninitializedFn _valtype_vec_new_uninitialized;
+  late WasmerWasmerLastErrorLengthFn _wasmer_last_error_length;
+  late WasmerWasmerLastErrorMessageFn _wasmer_last_error_message;
+
+  factory WasmRuntime() => _inst ??= WasmRuntime._init();
+
+  WasmRuntime._init() : _lib = DynamicLibrary.open(_getLibPath()) {
+    _Dart_InitializeApiDL = _lib.lookupFunction<
+        NativeWasmerDartInitializeApiDLFn, WasmerDartInitializeApiDLFn>(
+      'Dart_InitializeApiDL',
+    );
+    _set_finalizer_for_engine = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForEngineFn, WasmerSetFinalizerForEngineFn>(
+      'set_finalizer_for_engine',
+    );
+    _set_finalizer_for_func = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForFuncFn, WasmerSetFinalizerForFuncFn>(
+      'set_finalizer_for_func',
+    );
+    _set_finalizer_for_instance = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForInstanceFn, WasmerSetFinalizerForInstanceFn>(
+      'set_finalizer_for_instance',
+    );
+    _set_finalizer_for_memory = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForMemoryFn, WasmerSetFinalizerForMemoryFn>(
+      'set_finalizer_for_memory',
+    );
+    _set_finalizer_for_memorytype = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForMemorytypeFn,
+        WasmerSetFinalizerForMemorytypeFn>(
+      'set_finalizer_for_memorytype',
+    );
+    _set_finalizer_for_module = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForModuleFn, WasmerSetFinalizerForModuleFn>(
+      'set_finalizer_for_module',
+    );
+    _set_finalizer_for_store = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForStoreFn, WasmerSetFinalizerForStoreFn>(
+      'set_finalizer_for_store',
+    );
+    _set_finalizer_for_trap = _lib.lookupFunction<
+        NativeWasmerSetFinalizerForTrapFn, WasmerSetFinalizerForTrapFn>(
+      'set_finalizer_for_trap',
+    );
+    _wasi_config_inherit_stderr = _lib.lookupFunction<
+        NativeWasmerWasiConfigInheritStderrFn, WasmerWasiConfigInheritStderrFn>(
+      'wasi_config_inherit_stderr',
+    );
+    _wasi_config_inherit_stdout = _lib.lookupFunction<
+        NativeWasmerWasiConfigInheritStdoutFn, WasmerWasiConfigInheritStdoutFn>(
+      'wasi_config_inherit_stdout',
+    );
+    _wasi_config_new =
+        _lib.lookupFunction<NativeWasmerWasiConfigNewFn, WasmerWasiConfigNewFn>(
+      'wasi_config_new',
+    );
+    _wasi_env_delete =
+        _lib.lookupFunction<NativeWasmerWasiEnvDeleteFn, WasmerWasiEnvDeleteFn>(
+      'wasi_env_delete',
+    );
+    _wasi_env_new =
+        _lib.lookupFunction<NativeWasmerWasiEnvNewFn, WasmerWasiEnvNewFn>(
+      'wasi_env_new',
+    );
+    _wasi_env_read_stderr = _lib.lookupFunction<NativeWasmerWasiEnvReadStderrFn,
+        WasmerWasiEnvReadStderrFn>(
+      'wasi_env_read_stderr',
+    );
+    _wasi_env_read_stdout = _lib.lookupFunction<NativeWasmerWasiEnvReadStdoutFn,
+        WasmerWasiEnvReadStdoutFn>(
+      'wasi_env_read_stdout',
+    );
+    _wasi_env_set_memory = _lib.lookupFunction<NativeWasmerWasiEnvSetMemoryFn,
+        WasmerWasiEnvSetMemoryFn>(
+      'wasi_env_set_memory',
+    );
+    _wasi_get_imports = _lib
+        .lookupFunction<NativeWasmerWasiGetImportsFn, WasmerWasiGetImportsFn>(
+      'wasi_get_imports',
+    );
+    _byte_vec_delete =
+        _lib.lookupFunction<NativeWasmerByteVecDeleteFn, WasmerByteVecDeleteFn>(
+      'wasm_byte_vec_delete',
+    );
+    _byte_vec_new =
+        _lib.lookupFunction<NativeWasmerByteVecNewFn, WasmerByteVecNewFn>(
+      'wasm_byte_vec_new',
+    );
+    _byte_vec_new_empty = _lib
+        .lookupFunction<NativeWasmerByteVecNewEmptyFn, WasmerByteVecNewEmptyFn>(
+      'wasm_byte_vec_new_empty',
+    );
+    _byte_vec_new_uninitialized = _lib.lookupFunction<
+        NativeWasmerByteVecNewUninitializedFn, WasmerByteVecNewUninitializedFn>(
+      'wasm_byte_vec_new_uninitialized',
+    );
+    _engine_delete =
+        _lib.lookupFunction<NativeWasmerEngineDeleteFn, WasmerEngineDeleteFn>(
+      'wasm_engine_delete',
+    );
+    _engine_new =
+        _lib.lookupFunction<NativeWasmerEngineNewFn, WasmerEngineNewFn>(
+      'wasm_engine_new',
+    );
+    _exporttype_name = _lib
+        .lookupFunction<NativeWasmerExporttypeNameFn, WasmerExporttypeNameFn>(
+      'wasm_exporttype_name',
+    );
+    _exporttype_type = _lib
+        .lookupFunction<NativeWasmerExporttypeTypeFn, WasmerExporttypeTypeFn>(
+      'wasm_exporttype_type',
+    );
+    _exporttype_vec_delete = _lib.lookupFunction<
+        NativeWasmerExporttypeVecDeleteFn, WasmerExporttypeVecDeleteFn>(
+      'wasm_exporttype_vec_delete',
+    );
+    _exporttype_vec_new = _lib.lookupFunction<NativeWasmerExporttypeVecNewFn,
+        WasmerExporttypeVecNewFn>(
+      'wasm_exporttype_vec_new',
+    );
+    _exporttype_vec_new_empty = _lib.lookupFunction<
+        NativeWasmerExporttypeVecNewEmptyFn, WasmerExporttypeVecNewEmptyFn>(
+      'wasm_exporttype_vec_new_empty',
+    );
+    _exporttype_vec_new_uninitialized = _lib.lookupFunction<
+        NativeWasmerExporttypeVecNewUninitializedFn,
+        WasmerExporttypeVecNewUninitializedFn>(
+      'wasm_exporttype_vec_new_uninitialized',
+    );
+    _extern_as_func =
+        _lib.lookupFunction<NativeWasmerExternAsFuncFn, WasmerExternAsFuncFn>(
+      'wasm_extern_as_func',
+    );
+    _extern_as_memory = _lib
+        .lookupFunction<NativeWasmerExternAsMemoryFn, WasmerExternAsMemoryFn>(
+      'wasm_extern_as_memory',
+    );
+    _extern_delete =
+        _lib.lookupFunction<NativeWasmerExternDeleteFn, WasmerExternDeleteFn>(
+      'wasm_extern_delete',
+    );
+    _extern_kind =
+        _lib.lookupFunction<NativeWasmerExternKindFn, WasmerExternKindFn>(
+      'wasm_extern_kind',
+    );
+    _extern_vec_delete = _lib
+        .lookupFunction<NativeWasmerExternVecDeleteFn, WasmerExternVecDeleteFn>(
+      'wasm_extern_vec_delete',
+    );
+    _extern_vec_new =
+        _lib.lookupFunction<NativeWasmerExternVecNewFn, WasmerExternVecNewFn>(
+      'wasm_extern_vec_new',
+    );
+    _extern_vec_new_empty = _lib.lookupFunction<NativeWasmerExternVecNewEmptyFn,
+        WasmerExternVecNewEmptyFn>(
+      'wasm_extern_vec_new_empty',
+    );
+    _extern_vec_new_uninitialized = _lib.lookupFunction<
+        NativeWasmerExternVecNewUninitializedFn,
+        WasmerExternVecNewUninitializedFn>(
+      'wasm_extern_vec_new_uninitialized',
+    );
+    _externtype_as_functype = _lib.lookupFunction<
+        NativeWasmerExterntypeAsFunctypeFn, WasmerExterntypeAsFunctypeFn>(
+      'wasm_externtype_as_functype',
+    );
+    _externtype_delete = _lib.lookupFunction<NativeWasmerExterntypeDeleteFn,
+        WasmerExterntypeDeleteFn>(
+      'wasm_externtype_delete',
+    );
+    _externtype_kind = _lib
+        .lookupFunction<NativeWasmerExterntypeKindFn, WasmerExterntypeKindFn>(
+      'wasm_externtype_kind',
+    );
+    _func_as_extern =
+        _lib.lookupFunction<NativeWasmerFuncAsExternFn, WasmerFuncAsExternFn>(
+      'wasm_func_as_extern',
+    );
+    _func_call = _lib.lookupFunction<NativeWasmerFuncCallFn, WasmerFuncCallFn>(
+      'wasm_func_call',
+    );
+    _func_delete =
+        _lib.lookupFunction<NativeWasmerFuncDeleteFn, WasmerFuncDeleteFn>(
+      'wasm_func_delete',
+    );
+    _func_new_with_env = _lib
+        .lookupFunction<NativeWasmerFuncNewWithEnvFn, WasmerFuncNewWithEnvFn>(
+      'wasm_func_new_with_env',
+    );
+    _functype_delete = _lib
+        .lookupFunction<NativeWasmerFunctypeDeleteFn, WasmerFunctypeDeleteFn>(
+      'wasm_functype_delete',
+    );
+    _functype_params = _lib
+        .lookupFunction<NativeWasmerFunctypeParamsFn, WasmerFunctypeParamsFn>(
+      'wasm_functype_params',
+    );
+    _functype_results = _lib
+        .lookupFunction<NativeWasmerFunctypeResultsFn, WasmerFunctypeResultsFn>(
+      'wasm_functype_results',
+    );
+    _importtype_module = _lib.lookupFunction<NativeWasmerImporttypeModuleFn,
+        WasmerImporttypeModuleFn>(
+      'wasm_importtype_module',
+    );
+    _importtype_name = _lib
+        .lookupFunction<NativeWasmerImporttypeNameFn, WasmerImporttypeNameFn>(
+      'wasm_importtype_name',
+    );
+    _importtype_type = _lib
+        .lookupFunction<NativeWasmerImporttypeTypeFn, WasmerImporttypeTypeFn>(
+      'wasm_importtype_type',
+    );
+    _importtype_vec_delete = _lib.lookupFunction<
+        NativeWasmerImporttypeVecDeleteFn, WasmerImporttypeVecDeleteFn>(
+      'wasm_importtype_vec_delete',
+    );
+    _importtype_vec_new = _lib.lookupFunction<NativeWasmerImporttypeVecNewFn,
+        WasmerImporttypeVecNewFn>(
+      'wasm_importtype_vec_new',
+    );
+    _importtype_vec_new_empty = _lib.lookupFunction<
+        NativeWasmerImporttypeVecNewEmptyFn, WasmerImporttypeVecNewEmptyFn>(
+      'wasm_importtype_vec_new_empty',
+    );
+    _importtype_vec_new_uninitialized = _lib.lookupFunction<
+        NativeWasmerImporttypeVecNewUninitializedFn,
+        WasmerImporttypeVecNewUninitializedFn>(
+      'wasm_importtype_vec_new_uninitialized',
+    );
+    _instance_delete = _lib
+        .lookupFunction<NativeWasmerInstanceDeleteFn, WasmerInstanceDeleteFn>(
+      'wasm_instance_delete',
+    );
+    _instance_exports = _lib
+        .lookupFunction<NativeWasmerInstanceExportsFn, WasmerInstanceExportsFn>(
+      'wasm_instance_exports',
+    );
+    _instance_new =
+        _lib.lookupFunction<NativeWasmerInstanceNewFn, WasmerInstanceNewFn>(
+      'wasm_instance_new',
+    );
+    _memory_as_extern = _lib
+        .lookupFunction<NativeWasmerMemoryAsExternFn, WasmerMemoryAsExternFn>(
+      'wasm_memory_as_extern',
+    );
+    _memory_data =
+        _lib.lookupFunction<NativeWasmerMemoryDataFn, WasmerMemoryDataFn>(
+      'wasm_memory_data',
+    );
+    _memory_data_size = _lib
+        .lookupFunction<NativeWasmerMemoryDataSizeFn, WasmerMemoryDataSizeFn>(
+      'wasm_memory_data_size',
+    );
+    _memory_delete =
+        _lib.lookupFunction<NativeWasmerMemoryDeleteFn, WasmerMemoryDeleteFn>(
+      'wasm_memory_delete',
+    );
+    _memory_grow =
+        _lib.lookupFunction<NativeWasmerMemoryGrowFn, WasmerMemoryGrowFn>(
+      'wasm_memory_grow',
+    );
+    _memory_new =
+        _lib.lookupFunction<NativeWasmerMemoryNewFn, WasmerMemoryNewFn>(
+      'wasm_memory_new',
+    );
+    _memory_size =
+        _lib.lookupFunction<NativeWasmerMemorySizeFn, WasmerMemorySizeFn>(
+      'wasm_memory_size',
+    );
+    _memorytype_delete = _lib.lookupFunction<NativeWasmerMemorytypeDeleteFn,
+        WasmerMemorytypeDeleteFn>(
+      'wasm_memorytype_delete',
+    );
+    _memorytype_new =
+        _lib.lookupFunction<NativeWasmerMemorytypeNewFn, WasmerMemorytypeNewFn>(
+      'wasm_memorytype_new',
+    );
+    _module_delete =
+        _lib.lookupFunction<NativeWasmerModuleDeleteFn, WasmerModuleDeleteFn>(
+      'wasm_module_delete',
+    );
+    _module_exports =
+        _lib.lookupFunction<NativeWasmerModuleExportsFn, WasmerModuleExportsFn>(
+      'wasm_module_exports',
+    );
+    _module_imports =
+        _lib.lookupFunction<NativeWasmerModuleImportsFn, WasmerModuleImportsFn>(
+      'wasm_module_imports',
+    );
+    _module_new =
+        _lib.lookupFunction<NativeWasmerModuleNewFn, WasmerModuleNewFn>(
+      'wasm_module_new',
+    );
+    _store_delete =
+        _lib.lookupFunction<NativeWasmerStoreDeleteFn, WasmerStoreDeleteFn>(
+      'wasm_store_delete',
+    );
+    _store_new = _lib.lookupFunction<NativeWasmerStoreNewFn, WasmerStoreNewFn>(
+      'wasm_store_new',
+    );
+    _trap_delete =
+        _lib.lookupFunction<NativeWasmerTrapDeleteFn, WasmerTrapDeleteFn>(
+      'wasm_trap_delete',
+    );
+    _trap_message =
+        _lib.lookupFunction<NativeWasmerTrapMessageFn, WasmerTrapMessageFn>(
+      'wasm_trap_message',
+    );
+    _trap_new = _lib.lookupFunction<NativeWasmerTrapNewFn, WasmerTrapNewFn>(
+      'wasm_trap_new',
+    );
+    _valtype_delete =
+        _lib.lookupFunction<NativeWasmerValtypeDeleteFn, WasmerValtypeDeleteFn>(
+      'wasm_valtype_delete',
+    );
+    _valtype_kind =
+        _lib.lookupFunction<NativeWasmerValtypeKindFn, WasmerValtypeKindFn>(
+      'wasm_valtype_kind',
+    );
+    _valtype_vec_delete = _lib.lookupFunction<NativeWasmerValtypeVecDeleteFn,
+        WasmerValtypeVecDeleteFn>(
+      'wasm_valtype_vec_delete',
+    );
+    _valtype_vec_new =
+        _lib.lookupFunction<NativeWasmerValtypeVecNewFn, WasmerValtypeVecNewFn>(
+      'wasm_valtype_vec_new',
+    );
+    _valtype_vec_new_empty = _lib.lookupFunction<
+        NativeWasmerValtypeVecNewEmptyFn, WasmerValtypeVecNewEmptyFn>(
+      'wasm_valtype_vec_new_empty',
+    );
+    _valtype_vec_new_uninitialized = _lib.lookupFunction<
+        NativeWasmerValtypeVecNewUninitializedFn,
+        WasmerValtypeVecNewUninitializedFn>(
+      'wasm_valtype_vec_new_uninitialized',
+    );
+    _wasmer_last_error_length = _lib.lookupFunction<
+        NativeWasmerWasmerLastErrorLengthFn, WasmerWasmerLastErrorLengthFn>(
+      'wasmer_last_error_length',
+    );
+    _wasmer_last_error_message = _lib.lookupFunction<
+        NativeWasmerWasmerLastErrorMessageFn, WasmerWasmerLastErrorMessageFn>(
+      'wasmer_last_error_message',
+    );
+
+    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
+      throw Exception('Failed to initialize Dart API');
+    }
+    _engine = _engine_new();
+    _checkNotEqual(_engine, nullptr, 'Failed to initialize Wasm engine.');
+    _set_finalizer_for_engine(this, _engine);
+  }
+
+  Pointer<WasmerStore> newStore(Object owner) {
+    var store = _checkNotEqual(
+      _store_new(_engine),
+      nullptr,
+      'Failed to create Wasm store.',
+    );
+    _set_finalizer_for_store(owner, store);
+    return store;
+  }
+
+  Pointer<WasmerModule> compile(
+    Object owner,
+    Pointer<WasmerStore> store,
+    Uint8List data,
+  ) {
+    var dataPtr = calloc<Uint8>(data.length);
+    for (var i = 0; i < data.length; ++i) {
+      dataPtr[i] = data[i];
+    }
+    var dataVec = calloc<WasmerByteVec>();
+    dataVec.ref.data = dataPtr;
+    dataVec.ref.length = data.length;
+
+    var modulePtr = _module_new(store, dataVec);
+
+    calloc.free(dataPtr);
+    calloc.free(dataVec);
+
+    _checkNotEqual(modulePtr, nullptr, 'Wasm module compile failed.');
+    _set_finalizer_for_module(owner, modulePtr);
+    return modulePtr;
+  }
+
+  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
+    var exportsVec = calloc<WasmerExporttypeVec>();
+    _module_exports(module, exportsVec);
+    var exps = <WasmExportDescriptor>[];
+    for (var i = 0; i < exportsVec.ref.length; ++i) {
+      var exp = exportsVec.ref.data[i];
+      var extern = _exporttype_type(exp);
+      var kind = _externtype_kind(extern);
+      var fnType = kind == WasmerExternKindFunction
+          ? _externtype_as_functype(extern)
+          : nullptr;
+      exps.add(
+        WasmExportDescriptor(
+          kind,
+          _exporttype_name(exp).ref.toString(),
+          fnType,
+        ),
+      );
+    }
+    calloc.free(exportsVec);
+    return exps;
+  }
+
+  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
+    var importsVec = calloc<WasmerImporttypeVec>();
+    _module_imports(module, importsVec);
+    var imps = <WasmImportDescriptor>[];
+    for (var i = 0; i < importsVec.ref.length; ++i) {
+      var imp = importsVec.ref.data[i];
+      var extern = _importtype_type(imp);
+      var kind = _externtype_kind(extern);
+      var fnType = kind == WasmerExternKindFunction
+          ? _externtype_as_functype(extern)
+          : nullptr;
+      imps.add(
+        WasmImportDescriptor(
+          kind,
+          _importtype_module(imp).ref.toString(),
+          _importtype_name(imp).ref.toString(),
+          fnType,
+        ),
+      );
+    }
+    calloc.free(importsVec);
+    return imps;
+  }
+
+  void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
+    if (trap != nullptr) {
+      // There are 2 kinds of trap, and their memory is managed differently.
+      // Traps created in the newTrap method below are stored in the traps map
+      // with a corresponding exception, and their memory is managed using a
+      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
+      // code, and in that case we delete them in this function.
+      var entry = traps[trap.address];
+      if (entry != null) {
+        traps.remove(entry);
+        // ignore: only_throw_errors
+        throw entry.exception;
+      } else {
+        var trapMessage = calloc<WasmerByteVec>();
+        _trap_message(trap, trapMessage);
+        var message = 'Wasm trap when calling $source: ${trapMessage.ref}';
+        _byte_vec_delete(trapMessage);
+        calloc.free(trapMessage);
+        _trap_delete(trap);
+        throw Exception(message);
+      }
+    }
+  }
+
+  Pointer<WasmerInstance> instantiate(
+    Object owner,
+    Pointer<WasmerStore> store,
+    Pointer<WasmerModule> module,
+    Pointer<WasmerExternVec> imports,
+  ) {
+    var trap = calloc<Pointer<WasmerTrap>>();
+    trap.value = nullptr;
+    var inst = _instance_new(store, module, imports, trap);
+    maybeThrowTrap(trap.value, 'module initialization function');
+    calloc.free(trap);
+    _checkNotEqual(inst, nullptr, 'Wasm module instantiation failed.');
+    _set_finalizer_for_instance(owner, inst);
+    return inst;
+  }
+
+  // Clean up the exports after use, with deleteExports.
+  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
+    var exports = calloc<WasmerExternVec>();
+    _instance_exports(instancePtr, exports);
+    return exports;
+  }
+
+  void deleteExports(Pointer<WasmerExternVec> exports) {
+    _extern_vec_delete(exports);
+    calloc.free(exports);
+  }
+
+  int externKind(Pointer<WasmerExtern> extern) => _extern_kind(extern);
+
+  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) =>
+      _extern_as_func(extern);
+
+  Pointer<WasmerExtern> functionToExtern(Pointer<WasmerFunc> func) =>
+      _func_as_extern(func);
+
+  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
+    var types = <int>[];
+    var args = _functype_params(funcType);
+    for (var i = 0; i < args.ref.length; ++i) {
+      types.add(_valtype_kind(args.ref.data[i]));
+    }
+    return types;
+  }
+
+  int getReturnType(Pointer<WasmerFunctype> funcType) {
+    var rets = _functype_results(funcType);
+    if (rets.ref.length == 0) {
+      return WasmerValKindVoid;
+    } else if (rets.ref.length > 1) {
+      throw Exception('Multiple return values are not supported');
+    }
+    return _valtype_kind(rets.ref.data[0]);
+  }
+
+  void call(
+    Pointer<WasmerFunc> func,
+    Pointer<WasmerValVec> args,
+    Pointer<WasmerValVec> results,
+    String source,
+  ) {
+    maybeThrowTrap(_func_call(func, args, results), source);
+  }
+
+  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) =>
+      _extern_as_memory(extern);
+
+  Pointer<WasmerExtern> memoryToExtern(Pointer<WasmerMemory> memory) =>
+      _memory_as_extern(memory);
+
+  Pointer<WasmerMemory> newMemory(
+    Object owner,
+    Pointer<WasmerStore> store,
+    int pages,
+    int? maxPages,
+  ) {
+    var limPtr = calloc<WasmerLimits>();
+    limPtr.ref.min = pages;
+    limPtr.ref.max = maxPages ?? wasm_limits_max_default;
+    var memType = _memorytype_new(limPtr);
+    calloc.free(limPtr);
+    _checkNotEqual(memType, nullptr, 'Failed to create memory type.');
+    _set_finalizer_for_memorytype(owner, memType);
+    var memory = _checkNotEqual(
+      _memory_new(store, memType),
+      nullptr,
+      'Failed to create memory.',
+    );
+    _set_finalizer_for_memory(owner, memory);
+    return memory;
+  }
+
+  void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
+    _checkNotEqual(
+      _memory_grow(memory, deltaPages),
+      0,
+      'Failed to grow memory.',
+    );
+  }
+
+  int memoryLength(Pointer<WasmerMemory> memory) => _memory_size(memory);
+
+  Uint8List memoryView(Pointer<WasmerMemory> memory) =>
+      _memory_data(memory).asTypedList(_memory_data_size(memory));
+
+  Pointer<WasmerFunc> newFunc(
+    Object owner,
+    Pointer<WasmerStore> store,
+    Pointer<WasmerFunctype> funcType,
+    Pointer func,
+    Pointer env,
+    Pointer finalizer,
+  ) {
+    var f = _func_new_with_env(
+      store,
+      funcType,
+      func.cast(),
+      env.cast(),
+      finalizer.cast(),
+    );
+    _checkNotEqual(f, nullptr, 'Failed to create function.');
+    _set_finalizer_for_func(owner, f);
+    return f;
+  }
+
+  Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, Object exception) {
+    var msg = calloc<WasmerByteVec>();
+    msg.ref.data = calloc<Uint8>();
+    msg.ref.data[0] = 0;
+    msg.ref.length = 0;
+    var trap = _trap_new(store, msg);
+    calloc.free(msg.ref.data);
+    calloc.free(msg);
+    _checkNotEqual(trap, nullptr, 'Failed to create trap.');
+    var entry = _WasmTrapsEntry(exception);
+    _set_finalizer_for_trap(entry, trap);
+    traps[trap.address] = entry;
+    return trap;
+  }
+
+  Pointer<WasmerWasiConfig> newWasiConfig() {
+    var name = calloc<Uint8>();
+    name[0] = 0;
+    var config = _wasi_config_new(name);
+    calloc.free(name);
+    return _checkNotEqual(config, nullptr, 'Failed to create WASI config.');
+  }
+
+  void captureWasiStdout(Pointer<WasmerWasiConfig> config) {
+    _wasi_config_inherit_stdout(config);
+  }
+
+  void captureWasiStderr(Pointer<WasmerWasiConfig> config) {
+    _wasi_config_inherit_stderr(config);
+  }
+
+  Pointer<WasmerWasiEnv> newWasiEnv(Pointer<WasmerWasiConfig> config) =>
+      _checkNotEqual(
+        _wasi_env_new(config),
+        nullptr,
+        'Failed to create WASI environment.',
+      );
+
+  void wasiEnvSetMemory(
+    Pointer<WasmerWasiEnv> env,
+    Pointer<WasmerMemory> memory,
+  ) {
+    _wasi_env_set_memory(env, memory);
+  }
+
+  void getWasiImports(
+    Pointer<WasmerStore> store,
+    Pointer<WasmerModule> mod,
+    Pointer<WasmerWasiEnv> env,
+    Pointer<WasmerExternVec> imports,
+  ) {
+    _checkNotEqual(
+      _wasi_get_imports(store, mod, env, imports),
+      0,
+      'Failed to fill WASI imports.',
+    );
+  }
+
+  Stream<List<int>> getWasiStdoutStream(Pointer<WasmerWasiEnv> env) =>
+      Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stdout));
+
+  Stream<List<int>> getWasiStderrStream(Pointer<WasmerWasiEnv> env) =>
+      Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stderr));
+
+  String _getLastError() {
+    var length = _wasmer_last_error_length();
+    var buf = calloc<Uint8>(length);
+    _wasmer_last_error_message(buf, length);
+    var message = utf8.decode(buf.asTypedList(length));
+    calloc.free(buf);
+    return message;
+  }
+
+  T _checkNotEqual<T>(T x, T y, String errorMessage) {
+    if (x == y) {
+      throw Exception('$errorMessage\n${_getLastError()}');
+    }
+    return x;
+  }
+
+  static String getSignatureString(
+    String name,
+    List<int> argTypes,
+    int returnType,
+  ) =>
+      '${wasmerValKindName(returnType)} '
+      "$name(${argTypes.map(wasmerValKindName).join(", ")})";
+}
diff --git a/pkg/wasm/lib/src/tools/runtime_template.dart b/pkg/wasm/lib/src/tools/runtime_template.dart
deleted file mode 100644
index 072a042..0000000
--- a/pkg/wasm/lib/src/tools/runtime_template.dart
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/* <GEN_DOC> */
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:ffi';
-import 'dart:io';
-import 'dart:typed_data';
-import 'package:ffi/ffi.dart';
-import 'wasmer_api.dart';
-
-class WasmImportDescriptor {
-  int kind;
-  String moduleName;
-  String name;
-  Pointer<WasmerFunctype> funcType;
-  WasmImportDescriptor(this.kind, this.moduleName, this.name, this.funcType);
-
-  @override
-  String toString() {
-    var kindName = wasmerExternKindName(kind);
-    if (kind == WasmerExternKindFunction) {
-      var runtime = WasmRuntime();
-      var sig = WasmRuntime.getSignatureString('${moduleName}::${name}',
-          runtime.getArgTypes(funcType), runtime.getReturnType(funcType));
-      return '$kindName: $sig';
-    } else {
-      return '$kindName: ${moduleName}::${name}';
-    }
-  }
-}
-
-class WasmExportDescriptor {
-  int kind;
-  String name;
-  Pointer<WasmerFunctype> funcType;
-  WasmExportDescriptor(this.kind, this.name, this.funcType);
-
-  @override
-  String toString() {
-    var kindName = wasmerExternKindName(kind);
-    if (kind == WasmerExternKindFunction) {
-      var runtime = WasmRuntime();
-      var sig = WasmRuntime.getSignatureString(
-          name, runtime.getArgTypes(funcType), runtime.getReturnType(funcType));
-      return '$kindName: $sig';
-    } else {
-      return '$kindName: ${name}';
-    }
-  }
-}
-
-class _WasmTrapsEntry {
-  dynamic exception;
-  _WasmTrapsEntry(this.exception);
-}
-
-class WasmRuntime {
-  static WasmRuntime? _inst;
-
-  DynamicLibrary _lib;
-  late Pointer<WasmerEngine> _engine;
-  Map<int, _WasmTrapsEntry> traps = {};
-/* <RUNTIME_MEMB> */
-
-  factory WasmRuntime() {
-    return _inst ??= WasmRuntime._init();
-  }
-
-  static String _getLibName() {
-    if (Platform.isMacOS) return 'libwasmer.dylib';
-    if (Platform.isLinux) return 'libwasmer.so';
-    // TODO(dartbug.com/37882): Support more platforms.
-    throw Exception('Wasm not currently supported on this platform');
-  }
-
-  static String? _getLibPathFrom(Uri root) {
-    // The dynamic library created by pub run wasm:setup is located relative to
-    // the package_config.json file, so walk up from the script directory until
-    // we find it.
-    do {
-      if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
-          .existsSync()) {
-        return root.resolve('.dart_tool/wasm/' + _getLibName()).path;
-      }
-    } while (root != (root = root.resolve('..')));
-    return null;
-  }
-
-  static String _getLibPath() {
-    var path = _getLibPathFrom(Platform.script.resolve('./'));
-    if (path != null) return path;
-    path = _getLibPathFrom(Directory.current.uri);
-    if (path != null) return path;
-    throw Exception('Wasm library not found. Did you `pub run wasm:setup`?');
-  }
-
-  WasmRuntime._init() : _lib = DynamicLibrary.open(_getLibPath()) {
-/* <RUNTIME_LOAD> */
-
-    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
-      throw Exception('Failed to initialize Dart API');
-    }
-    _engine = _engine_new();
-    _checkNotEqual(_engine, nullptr, 'Failed to initialize Wasm engine.');
-    _set_finalizer_for_engine(this, _engine);
-  }
-
-  Pointer<WasmerStore> newStore(Object owner) {
-    var store = _checkNotEqual(
-        _store_new(_engine), nullptr, 'Failed to create Wasm store.');
-    _set_finalizer_for_store(owner, store);
-    return store;
-  }
-
-  Pointer<WasmerModule> compile(
-      Object owner, Pointer<WasmerStore> store, Uint8List data) {
-    var dataPtr = calloc<Uint8>(data.length);
-    for (var i = 0; i < data.length; ++i) {
-      dataPtr[i] = data[i];
-    }
-    var dataVec = calloc<WasmerByteVec>();
-    dataVec.ref.data = dataPtr;
-    dataVec.ref.length = data.length;
-
-    var modulePtr = _module_new(store, dataVec);
-
-    calloc.free(dataPtr);
-    calloc.free(dataVec);
-
-    _checkNotEqual(modulePtr, nullptr, 'Wasm module compile failed.');
-    _set_finalizer_for_module(owner, modulePtr);
-    return modulePtr;
-  }
-
-  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
-    var exportsVec = calloc<WasmerExporttypeVec>();
-    _module_exports(module, exportsVec);
-    var exps = <WasmExportDescriptor>[];
-    for (var i = 0; i < exportsVec.ref.length; ++i) {
-      var exp = exportsVec.ref.data[i];
-      var extern = _exporttype_type(exp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      exps.add(WasmExportDescriptor(
-          kind, _exporttype_name(exp).ref.toString(), fnType));
-    }
-    calloc.free(exportsVec);
-    return exps;
-  }
-
-  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
-    var importsVec = calloc<WasmerImporttypeVec>();
-    _module_imports(module, importsVec);
-    var imps = <WasmImportDescriptor>[];
-    for (var i = 0; i < importsVec.ref.length; ++i) {
-      var imp = importsVec.ref.data[i];
-      var extern = _importtype_type(imp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      imps.add(WasmImportDescriptor(
-          kind,
-          _importtype_module(imp).ref.toString(),
-          _importtype_name(imp).ref.toString(),
-          fnType));
-    }
-    calloc.free(importsVec);
-    return imps;
-  }
-
-  void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
-    if (trap != nullptr) {
-      // There are 2 kinds of trap, and their memory is managed differently.
-      // Traps created in the newTrap method below are stored in the traps map
-      // with a corresponding exception, and their memory is managed using a
-      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
-      // code, and in that case we delete them in this function.
-      var entry = traps[trap.address];
-      if (entry != null) {
-        traps.remove(entry);
-        throw entry.exception;
-      } else {
-        var trapMessage = calloc<WasmerByteVec>();
-        _trap_message(trap, trapMessage);
-        var message = 'Wasm trap when calling $source: ${trapMessage.ref}';
-        _byte_vec_delete(trapMessage);
-        calloc.free(trapMessage);
-        _trap_delete(trap);
-        throw Exception(message);
-      }
-    }
-  }
-
-  Pointer<WasmerInstance> instantiate(Object owner, Pointer<WasmerStore> store,
-      Pointer<WasmerModule> module, Pointer<WasmerExternVec> imports) {
-    var trap = calloc<Pointer<WasmerTrap>>();
-    trap.value = nullptr;
-    var inst = _instance_new(store, module, imports, trap);
-    maybeThrowTrap(trap.value, 'module initialization function');
-    calloc.free(trap);
-    _checkNotEqual(inst, nullptr, 'Wasm module instantiation failed.');
-    _set_finalizer_for_instance(owner, inst);
-    return inst;
-  }
-
-  // Clean up the exports after use, with deleteExports.
-  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
-    var exports = calloc<WasmerExternVec>();
-    _instance_exports(instancePtr, exports);
-    return exports;
-  }
-
-  void deleteExports(Pointer<WasmerExternVec> exports) {
-    _extern_vec_delete(exports);
-    calloc.free(exports);
-  }
-
-  int externKind(Pointer<WasmerExtern> extern) {
-    return _extern_kind(extern);
-  }
-
-  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) {
-    return _extern_as_func(extern);
-  }
-
-  Pointer<WasmerExtern> functionToExtern(Pointer<WasmerFunc> func) {
-    return _func_as_extern(func);
-  }
-
-  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
-    var types = <int>[];
-    var args = _functype_params(funcType);
-    for (var i = 0; i < args.ref.length; ++i) {
-      types.add(_valtype_kind(args.ref.data[i]));
-    }
-    return types;
-  }
-
-  int getReturnType(Pointer<WasmerFunctype> funcType) {
-    var rets = _functype_results(funcType);
-    if (rets.ref.length == 0) {
-      return WasmerValKindVoid;
-    } else if (rets.ref.length > 1) {
-      throw Exception('Multiple return values are not supported');
-    }
-    return _valtype_kind(rets.ref.data[0]);
-  }
-
-  void call(Pointer<WasmerFunc> func, Pointer<WasmerValVec> args,
-      Pointer<WasmerValVec> results, String source) {
-    maybeThrowTrap(_func_call(func, args, results), source);
-  }
-
-  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) {
-    return _extern_as_memory(extern);
-  }
-
-  Pointer<WasmerExtern> memoryToExtern(Pointer<WasmerMemory> memory) {
-    return _memory_as_extern(memory);
-  }
-
-  Pointer<WasmerMemory> newMemory(
-      Object owner, Pointer<WasmerStore> store, int pages, int? maxPages) {
-    var limPtr = calloc<WasmerLimits>();
-    limPtr.ref.min = pages;
-    limPtr.ref.max = maxPages ?? wasm_limits_max_default;
-    var memType = _memorytype_new(limPtr);
-    calloc.free(limPtr);
-    _checkNotEqual(memType, nullptr, 'Failed to create memory type.');
-    _set_finalizer_for_memorytype(owner, memType);
-    var memory = _checkNotEqual(
-        _memory_new(store, memType), nullptr, 'Failed to create memory.');
-    _set_finalizer_for_memory(owner, memory);
-    return memory;
-  }
-
-  void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
-    _checkNotEqual(
-        _memory_grow(memory, deltaPages), 0, 'Failed to grow memory.');
-  }
-
-  int memoryLength(Pointer<WasmerMemory> memory) {
-    return _memory_size(memory);
-  }
-
-  Uint8List memoryView(Pointer<WasmerMemory> memory) {
-    return _memory_data(memory).asTypedList(_memory_data_size(memory));
-  }
-
-  Pointer<WasmerFunc> newFunc(
-      Object owner,
-      Pointer<WasmerStore> store,
-      Pointer<WasmerFunctype> funcType,
-      Pointer func,
-      Pointer env,
-      Pointer finalizer) {
-    var f = _func_new_with_env(
-        store, funcType, func.cast(), env.cast(), finalizer.cast());
-    _checkNotEqual(f, nullptr, 'Failed to create function.');
-    _set_finalizer_for_func(owner, f);
-    return f;
-  }
-
-  Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, dynamic exception) {
-    var msg = calloc<WasmerByteVec>();
-    msg.ref.data = calloc<Uint8>();
-    msg.ref.data[0] = 0;
-    msg.ref.length = 0;
-    var trap = _trap_new(store, msg);
-    calloc.free(msg.ref.data);
-    calloc.free(msg);
-    _checkNotEqual(trap, nullptr, 'Failed to create trap.');
-    var entry = _WasmTrapsEntry(exception);
-    _set_finalizer_for_trap(entry, trap);
-    traps[trap.address] = entry;
-    return trap;
-  }
-
-  Pointer<WasmerWasiConfig> newWasiConfig() {
-    var name = calloc<Uint8>();
-    name[0] = 0;
-    var config = _wasi_config_new(name);
-    calloc.free(name);
-    return _checkNotEqual(config, nullptr, 'Failed to create WASI config.');
-  }
-
-  void captureWasiStdout(Pointer<WasmerWasiConfig> config) {
-    _wasi_config_inherit_stdout(config);
-  }
-
-  void captureWasiStderr(Pointer<WasmerWasiConfig> config) {
-    _wasi_config_inherit_stderr(config);
-  }
-
-  Pointer<WasmerWasiEnv> newWasiEnv(Pointer<WasmerWasiConfig> config) {
-    return _checkNotEqual(
-        _wasi_env_new(config), nullptr, 'Failed to create WASI environment.');
-  }
-
-  void wasiEnvSetMemory(
-      Pointer<WasmerWasiEnv> env, Pointer<WasmerMemory> memory) {
-    _wasi_env_set_memory(env, memory);
-  }
-
-  void getWasiImports(Pointer<WasmerStore> store, Pointer<WasmerModule> mod,
-      Pointer<WasmerWasiEnv> env, Pointer<WasmerExternVec> imports) {
-    _checkNotEqual(_wasi_get_imports(store, mod, env, imports), 0,
-        'Failed to fill WASI imports.');
-  }
-
-  Stream<List<int>> getWasiStdoutStream(Pointer<WasmerWasiEnv> env) {
-    return Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stdout));
-  }
-
-  Stream<List<int>> getWasiStderrStream(Pointer<WasmerWasiEnv> env) {
-    return Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stderr));
-  }
-
-  String _getLastError() {
-    var length = _wasmer_last_error_length();
-    var buf = calloc<Uint8>(length);
-    _wasmer_last_error_message(buf, length);
-    var message = utf8.decode(buf.asTypedList(length));
-    calloc.free(buf);
-    return message;
-  }
-
-  T _checkNotEqual<T>(T x, T y, String errorMessage) {
-    if (x == y) {
-      throw Exception('$errorMessage\n${_getLastError()}');
-    }
-    return x;
-  }
-
-  static String getSignatureString(
-      String name, List<int> argTypes, int returnType) {
-    return '${wasmerValKindName(returnType)} $name'
-        "(${argTypes.map(wasmerValKindName).join(", ")})";
-  }
-}
-
-class _WasiStreamIterator implements Iterator<List<int>> {
-  static final int _bufferLength = 1024;
-  final Pointer<WasmerWasiEnv> _env;
-  final Function _reader;
-  final Pointer<Uint8> _buf = calloc<Uint8>(_bufferLength);
-  int _length = 0;
-  _WasiStreamIterator(this._env, this._reader);
-
-  @override
-  bool moveNext() {
-    _length = _reader(_env, _buf, _bufferLength);
-    return true;
-  }
-
-  @override
-  List<int> get current => _buf.asTypedList(_length);
-}
-
-class _WasiStreamIterable extends Iterable<List<int>> {
-  final Pointer<WasmerWasiEnv> _env;
-  final Function _reader;
-  _WasiStreamIterable(this._env, this._reader);
-  @override
-  Iterator<List<int>> get iterator => _WasiStreamIterator(_env, _reader);
-}
diff --git a/pkg/wasm/lib/src/tools/wasmer_api_template.dart b/pkg/wasm/lib/src/tools/wasmer_api_template.dart
deleted file mode 100644
index f901c6e..0000000
--- a/pkg/wasm/lib/src/tools/wasmer_api_template.dart
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/* <GEN_DOC> */
-
-import 'dart:convert';
-import 'dart:ffi';
-import 'dart:typed_data';
-
-// wasm_valkind_enum
-const int WasmerValKindI32 = 0;
-const int WasmerValKindI64 = 1;
-const int WasmerValKindF32 = 2;
-const int WasmerValKindF64 = 3;
-// The void tag is not part of the C API. It's used to represent the return type
-// of a void function.
-const int WasmerValKindVoid = -1;
-
-// wasm_externkind_enum
-const int WasmerExternKindFunction = 0;
-const int WasmerExternKindGlobal = 1;
-const int WasmerExternKindTable = 2;
-const int WasmerExternKindMemory = 3;
-
-String wasmerExternKindName(int kind) {
-  switch (kind) {
-    case WasmerExternKindFunction:
-      return 'function';
-    case WasmerExternKindGlobal:
-      return 'global';
-    case WasmerExternKindTable:
-      return 'table';
-    case WasmerExternKindMemory:
-      return 'memory';
-    default:
-      return 'unknown';
-  }
-}
-
-String wasmerValKindName(int kind) {
-  switch (kind) {
-    case WasmerValKindI32:
-      return 'int32';
-    case WasmerValKindI64:
-      return 'int64';
-    case WasmerValKindF32:
-      return 'float32';
-    case WasmerValKindF64:
-      return 'float64';
-    case WasmerValKindVoid:
-      return 'void';
-    default:
-      return 'unknown';
-  }
-}
-
-// wasm_val_t
-class WasmerVal extends Struct {
-  // wasm_valkind_t
-  @Uint8()
-  external int kind;
-
-  // This is a union of int32_t, int64_t, float, and double. The kind determines
-  // which type it is. It's declared as an int64_t because that's large enough
-  // to hold all the types. We use ByteData to get the other types.
-  @Int64()
-  external int value;
-
-  int get _off32 => Endian.host == Endian.little ? 0 : 4;
-  int get i64 => value;
-  ByteData get _getterBytes => ByteData(8)..setInt64(0, value, Endian.host);
-  int get i32 => _getterBytes.getInt32(_off32, Endian.host);
-  double get f32 => _getterBytes.getFloat32(_off32, Endian.host);
-  double get f64 => _getterBytes.getFloat64(0, Endian.host);
-
-  set i64(int val) => value = val;
-  set _val(ByteData bytes) => value = bytes.getInt64(0, Endian.host);
-  set i32(int val) => _val = ByteData(8)..setInt32(_off32, val, Endian.host);
-  set f32(num val) =>
-      _val = ByteData(8)..setFloat32(_off32, val as double, Endian.host);
-  set f64(num val) =>
-      _val = ByteData(8)..setFloat64(0, val as double, Endian.host);
-
-  bool get isI32 => kind == WasmerValKindI32;
-  bool get isI64 => kind == WasmerValKindI64;
-  bool get isF32 => kind == WasmerValKindF32;
-  bool get isF64 => kind == WasmerValKindF64;
-
-  dynamic get toDynamic {
-    switch (kind) {
-      case WasmerValKindI32:
-        return i32;
-      case WasmerValKindI64:
-        return i64;
-      case WasmerValKindF32:
-        return f32;
-      case WasmerValKindF64:
-        return f64;
-    }
-  }
-}
-
-// wasmer_limits_t
-class WasmerLimits extends Struct {
-  @Uint32()
-  external int min;
-
-  @Uint32()
-  external int max;
-}
-
-// Default maximum, which indicates no upper limit.
-const int wasm_limits_max_default = 0xffffffff;
-
-/* <WASMER_API> */
diff --git a/pkg/wasm/lib/src/wasmer_api.dart b/pkg/wasm/lib/src/wasmer_api.dart
index 25bb8ba..28fa92d 100644
--- a/pkg/wasm/lib/src/wasmer_api.dart
+++ b/pkg/wasm/lib/src/wasmer_api.dart
@@ -6,10 +6,14 @@
 // To regenerate the file, use the following command
 // "generate_ffi_boilerplate.py".
 
+// ignore_for_file: constant_identifier_names
+
 import 'dart:convert';
 import 'dart:ffi';
 import 'dart:typed_data';
 
+part 'wasmer_api.g.dart';
+
 // wasm_valkind_enum
 const int WasmerValKindI32 = 0;
 const int WasmerValKindI64 = 1;
@@ -70,23 +74,35 @@
   external int value;
 
   int get _off32 => Endian.host == Endian.little ? 0 : 4;
+
   int get i64 => value;
+
   ByteData get _getterBytes => ByteData(8)..setInt64(0, value, Endian.host);
+
   int get i32 => _getterBytes.getInt32(_off32, Endian.host);
+
   double get f32 => _getterBytes.getFloat32(_off32, Endian.host);
+
   double get f64 => _getterBytes.getFloat64(0, Endian.host);
 
   set i64(int val) => value = val;
+
   set _val(ByteData bytes) => value = bytes.getInt64(0, Endian.host);
+
   set i32(int val) => _val = ByteData(8)..setInt32(_off32, val, Endian.host);
+
   set f32(num val) =>
       _val = ByteData(8)..setFloat32(_off32, val as double, Endian.host);
+
   set f64(num val) =>
       _val = ByteData(8)..setFloat64(0, val as double, Endian.host);
 
   bool get isI32 => kind == WasmerValKindI32;
+
   bool get isI64 => kind == WasmerValKindI64;
+
   bool get isF32 => kind == WasmerValKindF32;
+
   bool get isF64 => kind == WasmerValKindF64;
 
   dynamic get toDynamic {
@@ -114,569 +130,3 @@
 
 // Default maximum, which indicates no upper limit.
 const int wasm_limits_max_default = 0xffffffff;
-
-// wasm_engine_t
-class WasmerEngine extends Opaque {}
-
-// wasm_exporttype_t
-class WasmerExporttype extends Opaque {}
-
-// wasm_extern_t
-class WasmerExtern extends Opaque {}
-
-// wasm_externtype_t
-class WasmerExterntype extends Opaque {}
-
-// wasm_func_t
-class WasmerFunc extends Opaque {}
-
-// wasm_functype_t
-class WasmerFunctype extends Opaque {}
-
-// wasm_importtype_t
-class WasmerImporttype extends Opaque {}
-
-// wasm_instance_t
-class WasmerInstance extends Opaque {}
-
-// wasm_memory_t
-class WasmerMemory extends Opaque {}
-
-// wasm_memorytype_t
-class WasmerMemorytype extends Opaque {}
-
-// wasm_module_t
-class WasmerModule extends Opaque {}
-
-// wasm_store_t
-class WasmerStore extends Opaque {}
-
-// wasm_trap_t
-class WasmerTrap extends Opaque {}
-
-// wasm_valtype_t
-class WasmerValtype extends Opaque {}
-
-// wasi_config_t
-class WasmerWasiConfig extends Opaque {}
-
-// wasi_env_t
-class WasmerWasiEnv extends Opaque {}
-
-// wasm_byte_vec_t
-class WasmerByteVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Uint8> data;
-
-  Uint8List get list => data.asTypedList(length);
-  @override
-  String toString() => utf8.decode(list);
-}
-
-// wasm_exporttype_vec_t
-class WasmerExporttypeVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerExporttype>> data;
-}
-
-// wasm_extern_vec_t
-class WasmerExternVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerExtern>> data;
-}
-
-// wasm_importtype_vec_t
-class WasmerImporttypeVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerImporttype>> data;
-}
-
-// wasm_val_vec_t
-class WasmerValVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<WasmerVal> data;
-}
-
-// wasm_valtype_vec_t
-class WasmerValtypeVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerValtype>> data;
-}
-
-// Dart_InitializeApiDL
-typedef NativeWasmerDartInitializeApiDLFn = Int64 Function(Pointer<Void>);
-typedef WasmerDartInitializeApiDLFn = int Function(Pointer<Void>);
-
-// set_finalizer_for_engine
-typedef NativeWasmerSetFinalizerForEngineFn = Void Function(
-    Handle, Pointer<WasmerEngine>);
-typedef WasmerSetFinalizerForEngineFn = void Function(
-    Object, Pointer<WasmerEngine>);
-
-// set_finalizer_for_func
-typedef NativeWasmerSetFinalizerForFuncFn = Void Function(
-    Handle, Pointer<WasmerFunc>);
-typedef WasmerSetFinalizerForFuncFn = void Function(
-    Object, Pointer<WasmerFunc>);
-
-// set_finalizer_for_instance
-typedef NativeWasmerSetFinalizerForInstanceFn = Void Function(
-    Handle, Pointer<WasmerInstance>);
-typedef WasmerSetFinalizerForInstanceFn = void Function(
-    Object, Pointer<WasmerInstance>);
-
-// set_finalizer_for_memory
-typedef NativeWasmerSetFinalizerForMemoryFn = Void Function(
-    Handle, Pointer<WasmerMemory>);
-typedef WasmerSetFinalizerForMemoryFn = void Function(
-    Object, Pointer<WasmerMemory>);
-
-// set_finalizer_for_memorytype
-typedef NativeWasmerSetFinalizerForMemorytypeFn = Void Function(
-    Handle, Pointer<WasmerMemorytype>);
-typedef WasmerSetFinalizerForMemorytypeFn = void Function(
-    Object, Pointer<WasmerMemorytype>);
-
-// set_finalizer_for_module
-typedef NativeWasmerSetFinalizerForModuleFn = Void Function(
-    Handle, Pointer<WasmerModule>);
-typedef WasmerSetFinalizerForModuleFn = void Function(
-    Object, Pointer<WasmerModule>);
-
-// set_finalizer_for_store
-typedef NativeWasmerSetFinalizerForStoreFn = Void Function(
-    Handle, Pointer<WasmerStore>);
-typedef WasmerSetFinalizerForStoreFn = void Function(
-    Object, Pointer<WasmerStore>);
-
-// set_finalizer_for_trap
-typedef NativeWasmerSetFinalizerForTrapFn = Void Function(
-    Handle, Pointer<WasmerTrap>);
-typedef WasmerSetFinalizerForTrapFn = void Function(
-    Object, Pointer<WasmerTrap>);
-
-// wasi_config_inherit_stderr
-typedef NativeWasmerWasiConfigInheritStderrFn = Void Function(
-    Pointer<WasmerWasiConfig>);
-typedef WasmerWasiConfigInheritStderrFn = void Function(
-    Pointer<WasmerWasiConfig>);
-
-// wasi_config_inherit_stdout
-typedef NativeWasmerWasiConfigInheritStdoutFn = Void Function(
-    Pointer<WasmerWasiConfig>);
-typedef WasmerWasiConfigInheritStdoutFn = void Function(
-    Pointer<WasmerWasiConfig>);
-
-// wasi_config_new
-typedef NativeWasmerWasiConfigNewFn = Pointer<WasmerWasiConfig> Function(
-    Pointer<Uint8>);
-typedef WasmerWasiConfigNewFn = Pointer<WasmerWasiConfig> Function(
-    Pointer<Uint8>);
-
-// wasi_env_delete
-typedef NativeWasmerWasiEnvDeleteFn = Void Function(Pointer<WasmerWasiEnv>);
-typedef WasmerWasiEnvDeleteFn = void Function(Pointer<WasmerWasiEnv>);
-
-// wasi_env_new
-typedef NativeWasmerWasiEnvNewFn = Pointer<WasmerWasiEnv> Function(
-    Pointer<WasmerWasiConfig>);
-typedef WasmerWasiEnvNewFn = Pointer<WasmerWasiEnv> Function(
-    Pointer<WasmerWasiConfig>);
-
-// wasi_env_read_stderr
-typedef NativeWasmerWasiEnvReadStderrFn = Int64 Function(
-    Pointer<WasmerWasiEnv>, Pointer<Uint8>, Uint64);
-typedef WasmerWasiEnvReadStderrFn = int Function(
-    Pointer<WasmerWasiEnv>, Pointer<Uint8>, int);
-
-// wasi_env_read_stdout
-typedef NativeWasmerWasiEnvReadStdoutFn = Int64 Function(
-    Pointer<WasmerWasiEnv>, Pointer<Uint8>, Uint64);
-typedef WasmerWasiEnvReadStdoutFn = int Function(
-    Pointer<WasmerWasiEnv>, Pointer<Uint8>, int);
-
-// wasi_env_set_memory
-typedef NativeWasmerWasiEnvSetMemoryFn = Void Function(
-    Pointer<WasmerWasiEnv>, Pointer<WasmerMemory>);
-typedef WasmerWasiEnvSetMemoryFn = void Function(
-    Pointer<WasmerWasiEnv>, Pointer<WasmerMemory>);
-
-// wasi_get_imports
-typedef NativeWasmerWasiGetImportsFn = Uint8 Function(Pointer<WasmerStore>,
-    Pointer<WasmerModule>, Pointer<WasmerWasiEnv>, Pointer<WasmerExternVec>);
-typedef WasmerWasiGetImportsFn = int Function(Pointer<WasmerStore>,
-    Pointer<WasmerModule>, Pointer<WasmerWasiEnv>, Pointer<WasmerExternVec>);
-
-// wasm_byte_vec_delete
-typedef NativeWasmerByteVecDeleteFn = Void Function(Pointer<WasmerByteVec>);
-typedef WasmerByteVecDeleteFn = void Function(Pointer<WasmerByteVec>);
-
-// wasm_byte_vec_new
-typedef NativeWasmerByteVecNewFn = Void Function(
-    Pointer<WasmerByteVec>, Uint64, Pointer<Uint8>);
-typedef WasmerByteVecNewFn = void Function(
-    Pointer<WasmerByteVec>, int, Pointer<Uint8>);
-
-// wasm_byte_vec_new_empty
-typedef NativeWasmerByteVecNewEmptyFn = Void Function(Pointer<WasmerByteVec>);
-typedef WasmerByteVecNewEmptyFn = void Function(Pointer<WasmerByteVec>);
-
-// wasm_byte_vec_new_uninitialized
-typedef NativeWasmerByteVecNewUninitializedFn = Void Function(
-    Pointer<WasmerByteVec>, Uint64);
-typedef WasmerByteVecNewUninitializedFn = void Function(
-    Pointer<WasmerByteVec>, int);
-
-// wasm_engine_delete
-typedef NativeWasmerEngineDeleteFn = Void Function(Pointer<WasmerEngine>);
-typedef WasmerEngineDeleteFn = void Function(Pointer<WasmerEngine>);
-
-// wasm_engine_new
-typedef NativeWasmerEngineNewFn = Pointer<WasmerEngine> Function();
-typedef WasmerEngineNewFn = Pointer<WasmerEngine> Function();
-
-// wasm_exporttype_name
-typedef NativeWasmerExporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerExporttype>);
-typedef WasmerExporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerExporttype>);
-
-// wasm_exporttype_type
-typedef NativeWasmerExporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerExporttype>);
-typedef WasmerExporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerExporttype>);
-
-// wasm_exporttype_vec_delete
-typedef NativeWasmerExporttypeVecDeleteFn = Void Function(
-    Pointer<WasmerExporttypeVec>);
-typedef WasmerExporttypeVecDeleteFn = void Function(
-    Pointer<WasmerExporttypeVec>);
-
-// wasm_exporttype_vec_new
-typedef NativeWasmerExporttypeVecNewFn = Void Function(
-    Pointer<WasmerExporttypeVec>, Uint64, Pointer<Pointer<WasmerExporttype>>);
-typedef WasmerExporttypeVecNewFn = void Function(
-    Pointer<WasmerExporttypeVec>, int, Pointer<Pointer<WasmerExporttype>>);
-
-// wasm_exporttype_vec_new_empty
-typedef NativeWasmerExporttypeVecNewEmptyFn = Void Function(
-    Pointer<WasmerExporttypeVec>);
-typedef WasmerExporttypeVecNewEmptyFn = void Function(
-    Pointer<WasmerExporttypeVec>);
-
-// wasm_exporttype_vec_new_uninitialized
-typedef NativeWasmerExporttypeVecNewUninitializedFn = Void Function(
-    Pointer<WasmerExporttypeVec>, Uint64);
-typedef WasmerExporttypeVecNewUninitializedFn = void Function(
-    Pointer<WasmerExporttypeVec>, int);
-
-// wasm_extern_as_func
-typedef NativeWasmerExternAsFuncFn = Pointer<WasmerFunc> Function(
-    Pointer<WasmerExtern>);
-typedef WasmerExternAsFuncFn = Pointer<WasmerFunc> Function(
-    Pointer<WasmerExtern>);
-
-// wasm_extern_as_memory
-typedef NativeWasmerExternAsMemoryFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerExtern>);
-typedef WasmerExternAsMemoryFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerExtern>);
-
-// wasm_extern_delete
-typedef NativeWasmerExternDeleteFn = Void Function(Pointer<WasmerExtern>);
-typedef WasmerExternDeleteFn = void Function(Pointer<WasmerExtern>);
-
-// wasm_extern_kind
-typedef NativeWasmerExternKindFn = Uint8 Function(Pointer<WasmerExtern>);
-typedef WasmerExternKindFn = int Function(Pointer<WasmerExtern>);
-
-// wasm_extern_vec_delete
-typedef NativeWasmerExternVecDeleteFn = Void Function(Pointer<WasmerExternVec>);
-typedef WasmerExternVecDeleteFn = void Function(Pointer<WasmerExternVec>);
-
-// wasm_extern_vec_new
-typedef NativeWasmerExternVecNewFn = Void Function(
-    Pointer<WasmerExternVec>, Uint64, Pointer<Pointer<WasmerExtern>>);
-typedef WasmerExternVecNewFn = void Function(
-    Pointer<WasmerExternVec>, int, Pointer<Pointer<WasmerExtern>>);
-
-// wasm_extern_vec_new_empty
-typedef NativeWasmerExternVecNewEmptyFn = Void Function(
-    Pointer<WasmerExternVec>);
-typedef WasmerExternVecNewEmptyFn = void Function(Pointer<WasmerExternVec>);
-
-// wasm_extern_vec_new_uninitialized
-typedef NativeWasmerExternVecNewUninitializedFn = Void Function(
-    Pointer<WasmerExternVec>, Uint64);
-typedef WasmerExternVecNewUninitializedFn = void Function(
-    Pointer<WasmerExternVec>, int);
-
-// wasm_externtype_as_functype
-typedef NativeWasmerExterntypeAsFunctypeFn = Pointer<WasmerFunctype> Function(
-    Pointer<WasmerExterntype>);
-typedef WasmerExterntypeAsFunctypeFn = Pointer<WasmerFunctype> Function(
-    Pointer<WasmerExterntype>);
-
-// wasm_externtype_delete
-typedef NativeWasmerExterntypeDeleteFn = Void Function(
-    Pointer<WasmerExterntype>);
-typedef WasmerExterntypeDeleteFn = void Function(Pointer<WasmerExterntype>);
-
-// wasm_externtype_kind
-typedef NativeWasmerExterntypeKindFn = Uint8 Function(
-    Pointer<WasmerExterntype>);
-typedef WasmerExterntypeKindFn = int Function(Pointer<WasmerExterntype>);
-
-// wasm_func_as_extern
-typedef NativeWasmerFuncAsExternFn = Pointer<WasmerExtern> Function(
-    Pointer<WasmerFunc>);
-typedef WasmerFuncAsExternFn = Pointer<WasmerExtern> Function(
-    Pointer<WasmerFunc>);
-
-// wasm_func_call
-typedef NativeWasmerFuncCallFn = Pointer<WasmerTrap> Function(
-    Pointer<WasmerFunc>, Pointer<WasmerValVec>, Pointer<WasmerValVec>);
-typedef WasmerFuncCallFn = Pointer<WasmerTrap> Function(
-    Pointer<WasmerFunc>, Pointer<WasmerValVec>, Pointer<WasmerValVec>);
-
-// wasm_func_delete
-typedef NativeWasmerFuncDeleteFn = Void Function(Pointer<WasmerFunc>);
-typedef WasmerFuncDeleteFn = void Function(Pointer<WasmerFunc>);
-
-// wasm_func_new_with_env
-typedef NativeWasmerFuncNewWithEnvFn = Pointer<WasmerFunc> Function(
-    Pointer<WasmerStore>,
-    Pointer<WasmerFunctype>,
-    Pointer<Void>,
-    Pointer<Void>,
-    Pointer<Void>);
-typedef WasmerFuncNewWithEnvFn = Pointer<WasmerFunc> Function(
-    Pointer<WasmerStore>,
-    Pointer<WasmerFunctype>,
-    Pointer<Void>,
-    Pointer<Void>,
-    Pointer<Void>);
-
-// wasm_functype_delete
-typedef NativeWasmerFunctypeDeleteFn = Void Function(Pointer<WasmerFunctype>);
-typedef WasmerFunctypeDeleteFn = void Function(Pointer<WasmerFunctype>);
-
-// wasm_functype_params
-typedef NativeWasmerFunctypeParamsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-typedef WasmerFunctypeParamsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-
-// wasm_functype_results
-typedef NativeWasmerFunctypeResultsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-typedef WasmerFunctypeResultsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-
-// wasm_importtype_module
-typedef NativeWasmerImporttypeModuleFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-typedef WasmerImporttypeModuleFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-
-// wasm_importtype_name
-typedef NativeWasmerImporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-typedef WasmerImporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-
-// wasm_importtype_type
-typedef NativeWasmerImporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerImporttype>);
-typedef WasmerImporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerImporttype>);
-
-// wasm_importtype_vec_delete
-typedef NativeWasmerImporttypeVecDeleteFn = Void Function(
-    Pointer<WasmerImporttypeVec>);
-typedef WasmerImporttypeVecDeleteFn = void Function(
-    Pointer<WasmerImporttypeVec>);
-
-// wasm_importtype_vec_new
-typedef NativeWasmerImporttypeVecNewFn = Void Function(
-    Pointer<WasmerImporttypeVec>, Uint64, Pointer<Pointer<WasmerImporttype>>);
-typedef WasmerImporttypeVecNewFn = void Function(
-    Pointer<WasmerImporttypeVec>, int, Pointer<Pointer<WasmerImporttype>>);
-
-// wasm_importtype_vec_new_empty
-typedef NativeWasmerImporttypeVecNewEmptyFn = Void Function(
-    Pointer<WasmerImporttypeVec>);
-typedef WasmerImporttypeVecNewEmptyFn = void Function(
-    Pointer<WasmerImporttypeVec>);
-
-// wasm_importtype_vec_new_uninitialized
-typedef NativeWasmerImporttypeVecNewUninitializedFn = Void Function(
-    Pointer<WasmerImporttypeVec>, Uint64);
-typedef WasmerImporttypeVecNewUninitializedFn = void Function(
-    Pointer<WasmerImporttypeVec>, int);
-
-// wasm_instance_delete
-typedef NativeWasmerInstanceDeleteFn = Void Function(Pointer<WasmerInstance>);
-typedef WasmerInstanceDeleteFn = void Function(Pointer<WasmerInstance>);
-
-// wasm_instance_exports
-typedef NativeWasmerInstanceExportsFn = Void Function(
-    Pointer<WasmerInstance>, Pointer<WasmerExternVec>);
-typedef WasmerInstanceExportsFn = void Function(
-    Pointer<WasmerInstance>, Pointer<WasmerExternVec>);
-
-// wasm_instance_new
-typedef NativeWasmerInstanceNewFn = Pointer<WasmerInstance> Function(
-    Pointer<WasmerStore>,
-    Pointer<WasmerModule>,
-    Pointer<WasmerExternVec>,
-    Pointer<Pointer<WasmerTrap>>);
-typedef WasmerInstanceNewFn = Pointer<WasmerInstance> Function(
-    Pointer<WasmerStore>,
-    Pointer<WasmerModule>,
-    Pointer<WasmerExternVec>,
-    Pointer<Pointer<WasmerTrap>>);
-
-// wasm_memory_as_extern
-typedef NativeWasmerMemoryAsExternFn = Pointer<WasmerExtern> Function(
-    Pointer<WasmerMemory>);
-typedef WasmerMemoryAsExternFn = Pointer<WasmerExtern> Function(
-    Pointer<WasmerMemory>);
-
-// wasm_memory_data
-typedef NativeWasmerMemoryDataFn = Pointer<Uint8> Function(
-    Pointer<WasmerMemory>);
-typedef WasmerMemoryDataFn = Pointer<Uint8> Function(Pointer<WasmerMemory>);
-
-// wasm_memory_data_size
-typedef NativeWasmerMemoryDataSizeFn = Uint64 Function(Pointer<WasmerMemory>);
-typedef WasmerMemoryDataSizeFn = int Function(Pointer<WasmerMemory>);
-
-// wasm_memory_delete
-typedef NativeWasmerMemoryDeleteFn = Void Function(Pointer<WasmerMemory>);
-typedef WasmerMemoryDeleteFn = void Function(Pointer<WasmerMemory>);
-
-// wasm_memory_grow
-typedef NativeWasmerMemoryGrowFn = Uint8 Function(
-    Pointer<WasmerMemory>, Uint32);
-typedef WasmerMemoryGrowFn = int Function(Pointer<WasmerMemory>, int);
-
-// wasm_memory_new
-typedef NativeWasmerMemoryNewFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerStore>, Pointer<WasmerMemorytype>);
-typedef WasmerMemoryNewFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerStore>, Pointer<WasmerMemorytype>);
-
-// wasm_memory_size
-typedef NativeWasmerMemorySizeFn = Uint32 Function(Pointer<WasmerMemory>);
-typedef WasmerMemorySizeFn = int Function(Pointer<WasmerMemory>);
-
-// wasm_memorytype_delete
-typedef NativeWasmerMemorytypeDeleteFn = Void Function(
-    Pointer<WasmerMemorytype>);
-typedef WasmerMemorytypeDeleteFn = void Function(Pointer<WasmerMemorytype>);
-
-// wasm_memorytype_new
-typedef NativeWasmerMemorytypeNewFn = Pointer<WasmerMemorytype> Function(
-    Pointer<WasmerLimits>);
-typedef WasmerMemorytypeNewFn = Pointer<WasmerMemorytype> Function(
-    Pointer<WasmerLimits>);
-
-// wasm_module_delete
-typedef NativeWasmerModuleDeleteFn = Void Function(Pointer<WasmerModule>);
-typedef WasmerModuleDeleteFn = void Function(Pointer<WasmerModule>);
-
-// wasm_module_exports
-typedef NativeWasmerModuleExportsFn = Void Function(
-    Pointer<WasmerModule>, Pointer<WasmerExporttypeVec>);
-typedef WasmerModuleExportsFn = void Function(
-    Pointer<WasmerModule>, Pointer<WasmerExporttypeVec>);
-
-// wasm_module_imports
-typedef NativeWasmerModuleImportsFn = Void Function(
-    Pointer<WasmerModule>, Pointer<WasmerImporttypeVec>);
-typedef WasmerModuleImportsFn = void Function(
-    Pointer<WasmerModule>, Pointer<WasmerImporttypeVec>);
-
-// wasm_module_new
-typedef NativeWasmerModuleNewFn = Pointer<WasmerModule> Function(
-    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
-typedef WasmerModuleNewFn = Pointer<WasmerModule> Function(
-    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
-
-// wasm_store_delete
-typedef NativeWasmerStoreDeleteFn = Void Function(Pointer<WasmerStore>);
-typedef WasmerStoreDeleteFn = void Function(Pointer<WasmerStore>);
-
-// wasm_store_new
-typedef NativeWasmerStoreNewFn = Pointer<WasmerStore> Function(
-    Pointer<WasmerEngine>);
-typedef WasmerStoreNewFn = Pointer<WasmerStore> Function(Pointer<WasmerEngine>);
-
-// wasm_trap_delete
-typedef NativeWasmerTrapDeleteFn = Void Function(Pointer<WasmerTrap>);
-typedef WasmerTrapDeleteFn = void Function(Pointer<WasmerTrap>);
-
-// wasm_trap_message
-typedef NativeWasmerTrapMessageFn = Void Function(
-    Pointer<WasmerTrap>, Pointer<WasmerByteVec>);
-typedef WasmerTrapMessageFn = void Function(
-    Pointer<WasmerTrap>, Pointer<WasmerByteVec>);
-
-// wasm_trap_new
-typedef NativeWasmerTrapNewFn = Pointer<WasmerTrap> Function(
-    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
-typedef WasmerTrapNewFn = Pointer<WasmerTrap> Function(
-    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
-
-// wasm_valtype_delete
-typedef NativeWasmerValtypeDeleteFn = Void Function(Pointer<WasmerValtype>);
-typedef WasmerValtypeDeleteFn = void Function(Pointer<WasmerValtype>);
-
-// wasm_valtype_kind
-typedef NativeWasmerValtypeKindFn = Uint8 Function(Pointer<WasmerValtype>);
-typedef WasmerValtypeKindFn = int Function(Pointer<WasmerValtype>);
-
-// wasm_valtype_vec_delete
-typedef NativeWasmerValtypeVecDeleteFn = Void Function(
-    Pointer<WasmerValtypeVec>);
-typedef WasmerValtypeVecDeleteFn = void Function(Pointer<WasmerValtypeVec>);
-
-// wasm_valtype_vec_new
-typedef NativeWasmerValtypeVecNewFn = Void Function(
-    Pointer<WasmerValtypeVec>, Uint64, Pointer<Pointer<WasmerValtype>>);
-typedef WasmerValtypeVecNewFn = void Function(
-    Pointer<WasmerValtypeVec>, int, Pointer<Pointer<WasmerValtype>>);
-
-// wasm_valtype_vec_new_empty
-typedef NativeWasmerValtypeVecNewEmptyFn = Void Function(
-    Pointer<WasmerValtypeVec>);
-typedef WasmerValtypeVecNewEmptyFn = void Function(Pointer<WasmerValtypeVec>);
-
-// wasm_valtype_vec_new_uninitialized
-typedef NativeWasmerValtypeVecNewUninitializedFn = Void Function(
-    Pointer<WasmerValtypeVec>, Uint64);
-typedef WasmerValtypeVecNewUninitializedFn = void Function(
-    Pointer<WasmerValtypeVec>, int);
-
-// wasmer_last_error_length
-typedef NativeWasmerWasmerLastErrorLengthFn = Int64 Function();
-typedef WasmerWasmerLastErrorLengthFn = int Function();
-
-// wasmer_last_error_message
-typedef NativeWasmerWasmerLastErrorMessageFn = Int64 Function(
-    Pointer<Uint8>, Int64);
-typedef WasmerWasmerLastErrorMessageFn = int Function(Pointer<Uint8>, int);
diff --git a/pkg/wasm/lib/src/wasmer_api.g.dart b/pkg/wasm/lib/src/wasmer_api.g.dart
new file mode 100644
index 0000000..4211e7f
--- /dev/null
+++ b/pkg/wasm/lib/src/wasmer_api.g.dart
@@ -0,0 +1,577 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the following command
+// "generate_ffi_boilerplate.py".
+
+// ignore_for_file: require_trailing_commas
+
+part of 'wasmer_api.dart';
+
+// wasm_engine_t
+class WasmerEngine extends Opaque {}
+
+// wasm_exporttype_t
+class WasmerExporttype extends Opaque {}
+
+// wasm_extern_t
+class WasmerExtern extends Opaque {}
+
+// wasm_externtype_t
+class WasmerExterntype extends Opaque {}
+
+// wasm_func_t
+class WasmerFunc extends Opaque {}
+
+// wasm_functype_t
+class WasmerFunctype extends Opaque {}
+
+// wasm_importtype_t
+class WasmerImporttype extends Opaque {}
+
+// wasm_instance_t
+class WasmerInstance extends Opaque {}
+
+// wasm_memory_t
+class WasmerMemory extends Opaque {}
+
+// wasm_memorytype_t
+class WasmerMemorytype extends Opaque {}
+
+// wasm_module_t
+class WasmerModule extends Opaque {}
+
+// wasm_store_t
+class WasmerStore extends Opaque {}
+
+// wasm_trap_t
+class WasmerTrap extends Opaque {}
+
+// wasm_valtype_t
+class WasmerValtype extends Opaque {}
+
+// wasi_config_t
+class WasmerWasiConfig extends Opaque {}
+
+// wasi_env_t
+class WasmerWasiEnv extends Opaque {}
+
+// wasm_byte_vec_t
+class WasmerByteVec extends Struct {
+  @Uint64()
+  external int length;
+
+  external Pointer<Uint8> data;
+
+  Uint8List get list => data.asTypedList(length);
+  @override
+  String toString() => utf8.decode(list);
+}
+
+// wasm_exporttype_vec_t
+class WasmerExporttypeVec extends Struct {
+  @Uint64()
+  external int length;
+
+  external Pointer<Pointer<WasmerExporttype>> data;
+}
+
+// wasm_extern_vec_t
+class WasmerExternVec extends Struct {
+  @Uint64()
+  external int length;
+
+  external Pointer<Pointer<WasmerExtern>> data;
+}
+
+// wasm_importtype_vec_t
+class WasmerImporttypeVec extends Struct {
+  @Uint64()
+  external int length;
+
+  external Pointer<Pointer<WasmerImporttype>> data;
+}
+
+// wasm_val_vec_t
+class WasmerValVec extends Struct {
+  @Uint64()
+  external int length;
+
+  external Pointer<WasmerVal> data;
+}
+
+// wasm_valtype_vec_t
+class WasmerValtypeVec extends Struct {
+  @Uint64()
+  external int length;
+
+  external Pointer<Pointer<WasmerValtype>> data;
+}
+
+// Dart_InitializeApiDL
+typedef NativeWasmerDartInitializeApiDLFn = Int64 Function(Pointer<Void>);
+typedef WasmerDartInitializeApiDLFn = int Function(Pointer<Void>);
+
+// set_finalizer_for_engine
+typedef NativeWasmerSetFinalizerForEngineFn = Void Function(
+    Handle, Pointer<WasmerEngine>);
+typedef WasmerSetFinalizerForEngineFn = void Function(
+    Object, Pointer<WasmerEngine>);
+
+// set_finalizer_for_func
+typedef NativeWasmerSetFinalizerForFuncFn = Void Function(
+    Handle, Pointer<WasmerFunc>);
+typedef WasmerSetFinalizerForFuncFn = void Function(
+    Object, Pointer<WasmerFunc>);
+
+// set_finalizer_for_instance
+typedef NativeWasmerSetFinalizerForInstanceFn = Void Function(
+    Handle, Pointer<WasmerInstance>);
+typedef WasmerSetFinalizerForInstanceFn = void Function(
+    Object, Pointer<WasmerInstance>);
+
+// set_finalizer_for_memory
+typedef NativeWasmerSetFinalizerForMemoryFn = Void Function(
+    Handle, Pointer<WasmerMemory>);
+typedef WasmerSetFinalizerForMemoryFn = void Function(
+    Object, Pointer<WasmerMemory>);
+
+// set_finalizer_for_memorytype
+typedef NativeWasmerSetFinalizerForMemorytypeFn = Void Function(
+    Handle, Pointer<WasmerMemorytype>);
+typedef WasmerSetFinalizerForMemorytypeFn = void Function(
+    Object, Pointer<WasmerMemorytype>);
+
+// set_finalizer_for_module
+typedef NativeWasmerSetFinalizerForModuleFn = Void Function(
+    Handle, Pointer<WasmerModule>);
+typedef WasmerSetFinalizerForModuleFn = void Function(
+    Object, Pointer<WasmerModule>);
+
+// set_finalizer_for_store
+typedef NativeWasmerSetFinalizerForStoreFn = Void Function(
+    Handle, Pointer<WasmerStore>);
+typedef WasmerSetFinalizerForStoreFn = void Function(
+    Object, Pointer<WasmerStore>);
+
+// set_finalizer_for_trap
+typedef NativeWasmerSetFinalizerForTrapFn = Void Function(
+    Handle, Pointer<WasmerTrap>);
+typedef WasmerSetFinalizerForTrapFn = void Function(
+    Object, Pointer<WasmerTrap>);
+
+// wasi_config_inherit_stderr
+typedef NativeWasmerWasiConfigInheritStderrFn = Void Function(
+    Pointer<WasmerWasiConfig>);
+typedef WasmerWasiConfigInheritStderrFn = void Function(
+    Pointer<WasmerWasiConfig>);
+
+// wasi_config_inherit_stdout
+typedef NativeWasmerWasiConfigInheritStdoutFn = Void Function(
+    Pointer<WasmerWasiConfig>);
+typedef WasmerWasiConfigInheritStdoutFn = void Function(
+    Pointer<WasmerWasiConfig>);
+
+// wasi_config_new
+typedef NativeWasmerWasiConfigNewFn = Pointer<WasmerWasiConfig> Function(
+    Pointer<Uint8>);
+typedef WasmerWasiConfigNewFn = Pointer<WasmerWasiConfig> Function(
+    Pointer<Uint8>);
+
+// wasi_env_delete
+typedef NativeWasmerWasiEnvDeleteFn = Void Function(Pointer<WasmerWasiEnv>);
+typedef WasmerWasiEnvDeleteFn = void Function(Pointer<WasmerWasiEnv>);
+
+// wasi_env_new
+typedef NativeWasmerWasiEnvNewFn = Pointer<WasmerWasiEnv> Function(
+    Pointer<WasmerWasiConfig>);
+typedef WasmerWasiEnvNewFn = Pointer<WasmerWasiEnv> Function(
+    Pointer<WasmerWasiConfig>);
+
+// wasi_env_read_stderr
+typedef NativeWasmerWasiEnvReadStderrFn = Int64 Function(
+    Pointer<WasmerWasiEnv>, Pointer<Uint8>, Uint64);
+typedef WasmerWasiEnvReadStderrFn = int Function(
+    Pointer<WasmerWasiEnv>, Pointer<Uint8>, int);
+
+// wasi_env_read_stdout
+typedef NativeWasmerWasiEnvReadStdoutFn = Int64 Function(
+    Pointer<WasmerWasiEnv>, Pointer<Uint8>, Uint64);
+typedef WasmerWasiEnvReadStdoutFn = int Function(
+    Pointer<WasmerWasiEnv>, Pointer<Uint8>, int);
+
+// wasi_env_set_memory
+typedef NativeWasmerWasiEnvSetMemoryFn = Void Function(
+    Pointer<WasmerWasiEnv>, Pointer<WasmerMemory>);
+typedef WasmerWasiEnvSetMemoryFn = void Function(
+    Pointer<WasmerWasiEnv>, Pointer<WasmerMemory>);
+
+// wasi_get_imports
+typedef NativeWasmerWasiGetImportsFn = Uint8 Function(Pointer<WasmerStore>,
+    Pointer<WasmerModule>, Pointer<WasmerWasiEnv>, Pointer<WasmerExternVec>);
+typedef WasmerWasiGetImportsFn = int Function(Pointer<WasmerStore>,
+    Pointer<WasmerModule>, Pointer<WasmerWasiEnv>, Pointer<WasmerExternVec>);
+
+// wasm_byte_vec_delete
+typedef NativeWasmerByteVecDeleteFn = Void Function(Pointer<WasmerByteVec>);
+typedef WasmerByteVecDeleteFn = void Function(Pointer<WasmerByteVec>);
+
+// wasm_byte_vec_new
+typedef NativeWasmerByteVecNewFn = Void Function(
+    Pointer<WasmerByteVec>, Uint64, Pointer<Uint8>);
+typedef WasmerByteVecNewFn = void Function(
+    Pointer<WasmerByteVec>, int, Pointer<Uint8>);
+
+// wasm_byte_vec_new_empty
+typedef NativeWasmerByteVecNewEmptyFn = Void Function(Pointer<WasmerByteVec>);
+typedef WasmerByteVecNewEmptyFn = void Function(Pointer<WasmerByteVec>);
+
+// wasm_byte_vec_new_uninitialized
+typedef NativeWasmerByteVecNewUninitializedFn = Void Function(
+    Pointer<WasmerByteVec>, Uint64);
+typedef WasmerByteVecNewUninitializedFn = void Function(
+    Pointer<WasmerByteVec>, int);
+
+// wasm_engine_delete
+typedef NativeWasmerEngineDeleteFn = Void Function(Pointer<WasmerEngine>);
+typedef WasmerEngineDeleteFn = void Function(Pointer<WasmerEngine>);
+
+// wasm_engine_new
+typedef NativeWasmerEngineNewFn = Pointer<WasmerEngine> Function();
+typedef WasmerEngineNewFn = Pointer<WasmerEngine> Function();
+
+// wasm_exporttype_name
+typedef NativeWasmerExporttypeNameFn = Pointer<WasmerByteVec> Function(
+    Pointer<WasmerExporttype>);
+typedef WasmerExporttypeNameFn = Pointer<WasmerByteVec> Function(
+    Pointer<WasmerExporttype>);
+
+// wasm_exporttype_type
+typedef NativeWasmerExporttypeTypeFn = Pointer<WasmerExterntype> Function(
+    Pointer<WasmerExporttype>);
+typedef WasmerExporttypeTypeFn = Pointer<WasmerExterntype> Function(
+    Pointer<WasmerExporttype>);
+
+// wasm_exporttype_vec_delete
+typedef NativeWasmerExporttypeVecDeleteFn = Void Function(
+    Pointer<WasmerExporttypeVec>);
+typedef WasmerExporttypeVecDeleteFn = void Function(
+    Pointer<WasmerExporttypeVec>);
+
+// wasm_exporttype_vec_new
+typedef NativeWasmerExporttypeVecNewFn = Void Function(
+    Pointer<WasmerExporttypeVec>, Uint64, Pointer<Pointer<WasmerExporttype>>);
+typedef WasmerExporttypeVecNewFn = void Function(
+    Pointer<WasmerExporttypeVec>, int, Pointer<Pointer<WasmerExporttype>>);
+
+// wasm_exporttype_vec_new_empty
+typedef NativeWasmerExporttypeVecNewEmptyFn = Void Function(
+    Pointer<WasmerExporttypeVec>);
+typedef WasmerExporttypeVecNewEmptyFn = void Function(
+    Pointer<WasmerExporttypeVec>);
+
+// wasm_exporttype_vec_new_uninitialized
+typedef NativeWasmerExporttypeVecNewUninitializedFn = Void Function(
+    Pointer<WasmerExporttypeVec>, Uint64);
+typedef WasmerExporttypeVecNewUninitializedFn = void Function(
+    Pointer<WasmerExporttypeVec>, int);
+
+// wasm_extern_as_func
+typedef NativeWasmerExternAsFuncFn = Pointer<WasmerFunc> Function(
+    Pointer<WasmerExtern>);
+typedef WasmerExternAsFuncFn = Pointer<WasmerFunc> Function(
+    Pointer<WasmerExtern>);
+
+// wasm_extern_as_memory
+typedef NativeWasmerExternAsMemoryFn = Pointer<WasmerMemory> Function(
+    Pointer<WasmerExtern>);
+typedef WasmerExternAsMemoryFn = Pointer<WasmerMemory> Function(
+    Pointer<WasmerExtern>);
+
+// wasm_extern_delete
+typedef NativeWasmerExternDeleteFn = Void Function(Pointer<WasmerExtern>);
+typedef WasmerExternDeleteFn = void Function(Pointer<WasmerExtern>);
+
+// wasm_extern_kind
+typedef NativeWasmerExternKindFn = Uint8 Function(Pointer<WasmerExtern>);
+typedef WasmerExternKindFn = int Function(Pointer<WasmerExtern>);
+
+// wasm_extern_vec_delete
+typedef NativeWasmerExternVecDeleteFn = Void Function(Pointer<WasmerExternVec>);
+typedef WasmerExternVecDeleteFn = void Function(Pointer<WasmerExternVec>);
+
+// wasm_extern_vec_new
+typedef NativeWasmerExternVecNewFn = Void Function(
+    Pointer<WasmerExternVec>, Uint64, Pointer<Pointer<WasmerExtern>>);
+typedef WasmerExternVecNewFn = void Function(
+    Pointer<WasmerExternVec>, int, Pointer<Pointer<WasmerExtern>>);
+
+// wasm_extern_vec_new_empty
+typedef NativeWasmerExternVecNewEmptyFn = Void Function(
+    Pointer<WasmerExternVec>);
+typedef WasmerExternVecNewEmptyFn = void Function(Pointer<WasmerExternVec>);
+
+// wasm_extern_vec_new_uninitialized
+typedef NativeWasmerExternVecNewUninitializedFn = Void Function(
+    Pointer<WasmerExternVec>, Uint64);
+typedef WasmerExternVecNewUninitializedFn = void Function(
+    Pointer<WasmerExternVec>, int);
+
+// wasm_externtype_as_functype
+typedef NativeWasmerExterntypeAsFunctypeFn = Pointer<WasmerFunctype> Function(
+    Pointer<WasmerExterntype>);
+typedef WasmerExterntypeAsFunctypeFn = Pointer<WasmerFunctype> Function(
+    Pointer<WasmerExterntype>);
+
+// wasm_externtype_delete
+typedef NativeWasmerExterntypeDeleteFn = Void Function(
+    Pointer<WasmerExterntype>);
+typedef WasmerExterntypeDeleteFn = void Function(Pointer<WasmerExterntype>);
+
+// wasm_externtype_kind
+typedef NativeWasmerExterntypeKindFn = Uint8 Function(
+    Pointer<WasmerExterntype>);
+typedef WasmerExterntypeKindFn = int Function(Pointer<WasmerExterntype>);
+
+// wasm_func_as_extern
+typedef NativeWasmerFuncAsExternFn = Pointer<WasmerExtern> Function(
+    Pointer<WasmerFunc>);
+typedef WasmerFuncAsExternFn = Pointer<WasmerExtern> Function(
+    Pointer<WasmerFunc>);
+
+// wasm_func_call
+typedef NativeWasmerFuncCallFn = Pointer<WasmerTrap> Function(
+    Pointer<WasmerFunc>, Pointer<WasmerValVec>, Pointer<WasmerValVec>);
+typedef WasmerFuncCallFn = Pointer<WasmerTrap> Function(
+    Pointer<WasmerFunc>, Pointer<WasmerValVec>, Pointer<WasmerValVec>);
+
+// wasm_func_delete
+typedef NativeWasmerFuncDeleteFn = Void Function(Pointer<WasmerFunc>);
+typedef WasmerFuncDeleteFn = void Function(Pointer<WasmerFunc>);
+
+// wasm_func_new_with_env
+typedef NativeWasmerFuncNewWithEnvFn = Pointer<WasmerFunc> Function(
+    Pointer<WasmerStore>,
+    Pointer<WasmerFunctype>,
+    Pointer<Void>,
+    Pointer<Void>,
+    Pointer<Void>);
+typedef WasmerFuncNewWithEnvFn = Pointer<WasmerFunc> Function(
+    Pointer<WasmerStore>,
+    Pointer<WasmerFunctype>,
+    Pointer<Void>,
+    Pointer<Void>,
+    Pointer<Void>);
+
+// wasm_functype_delete
+typedef NativeWasmerFunctypeDeleteFn = Void Function(Pointer<WasmerFunctype>);
+typedef WasmerFunctypeDeleteFn = void Function(Pointer<WasmerFunctype>);
+
+// wasm_functype_params
+typedef NativeWasmerFunctypeParamsFn = Pointer<WasmerValtypeVec> Function(
+    Pointer<WasmerFunctype>);
+typedef WasmerFunctypeParamsFn = Pointer<WasmerValtypeVec> Function(
+    Pointer<WasmerFunctype>);
+
+// wasm_functype_results
+typedef NativeWasmerFunctypeResultsFn = Pointer<WasmerValtypeVec> Function(
+    Pointer<WasmerFunctype>);
+typedef WasmerFunctypeResultsFn = Pointer<WasmerValtypeVec> Function(
+    Pointer<WasmerFunctype>);
+
+// wasm_importtype_module
+typedef NativeWasmerImporttypeModuleFn = Pointer<WasmerByteVec> Function(
+    Pointer<WasmerImporttype>);
+typedef WasmerImporttypeModuleFn = Pointer<WasmerByteVec> Function(
+    Pointer<WasmerImporttype>);
+
+// wasm_importtype_name
+typedef NativeWasmerImporttypeNameFn = Pointer<WasmerByteVec> Function(
+    Pointer<WasmerImporttype>);
+typedef WasmerImporttypeNameFn = Pointer<WasmerByteVec> Function(
+    Pointer<WasmerImporttype>);
+
+// wasm_importtype_type
+typedef NativeWasmerImporttypeTypeFn = Pointer<WasmerExterntype> Function(
+    Pointer<WasmerImporttype>);
+typedef WasmerImporttypeTypeFn = Pointer<WasmerExterntype> Function(
+    Pointer<WasmerImporttype>);
+
+// wasm_importtype_vec_delete
+typedef NativeWasmerImporttypeVecDeleteFn = Void Function(
+    Pointer<WasmerImporttypeVec>);
+typedef WasmerImporttypeVecDeleteFn = void Function(
+    Pointer<WasmerImporttypeVec>);
+
+// wasm_importtype_vec_new
+typedef NativeWasmerImporttypeVecNewFn = Void Function(
+    Pointer<WasmerImporttypeVec>, Uint64, Pointer<Pointer<WasmerImporttype>>);
+typedef WasmerImporttypeVecNewFn = void Function(
+    Pointer<WasmerImporttypeVec>, int, Pointer<Pointer<WasmerImporttype>>);
+
+// wasm_importtype_vec_new_empty
+typedef NativeWasmerImporttypeVecNewEmptyFn = Void Function(
+    Pointer<WasmerImporttypeVec>);
+typedef WasmerImporttypeVecNewEmptyFn = void Function(
+    Pointer<WasmerImporttypeVec>);
+
+// wasm_importtype_vec_new_uninitialized
+typedef NativeWasmerImporttypeVecNewUninitializedFn = Void Function(
+    Pointer<WasmerImporttypeVec>, Uint64);
+typedef WasmerImporttypeVecNewUninitializedFn = void Function(
+    Pointer<WasmerImporttypeVec>, int);
+
+// wasm_instance_delete
+typedef NativeWasmerInstanceDeleteFn = Void Function(Pointer<WasmerInstance>);
+typedef WasmerInstanceDeleteFn = void Function(Pointer<WasmerInstance>);
+
+// wasm_instance_exports
+typedef NativeWasmerInstanceExportsFn = Void Function(
+    Pointer<WasmerInstance>, Pointer<WasmerExternVec>);
+typedef WasmerInstanceExportsFn = void Function(
+    Pointer<WasmerInstance>, Pointer<WasmerExternVec>);
+
+// wasm_instance_new
+typedef NativeWasmerInstanceNewFn = Pointer<WasmerInstance> Function(
+    Pointer<WasmerStore>,
+    Pointer<WasmerModule>,
+    Pointer<WasmerExternVec>,
+    Pointer<Pointer<WasmerTrap>>);
+typedef WasmerInstanceNewFn = Pointer<WasmerInstance> Function(
+    Pointer<WasmerStore>,
+    Pointer<WasmerModule>,
+    Pointer<WasmerExternVec>,
+    Pointer<Pointer<WasmerTrap>>);
+
+// wasm_memory_as_extern
+typedef NativeWasmerMemoryAsExternFn = Pointer<WasmerExtern> Function(
+    Pointer<WasmerMemory>);
+typedef WasmerMemoryAsExternFn = Pointer<WasmerExtern> Function(
+    Pointer<WasmerMemory>);
+
+// wasm_memory_data
+typedef NativeWasmerMemoryDataFn = Pointer<Uint8> Function(
+    Pointer<WasmerMemory>);
+typedef WasmerMemoryDataFn = Pointer<Uint8> Function(Pointer<WasmerMemory>);
+
+// wasm_memory_data_size
+typedef NativeWasmerMemoryDataSizeFn = Uint64 Function(Pointer<WasmerMemory>);
+typedef WasmerMemoryDataSizeFn = int Function(Pointer<WasmerMemory>);
+
+// wasm_memory_delete
+typedef NativeWasmerMemoryDeleteFn = Void Function(Pointer<WasmerMemory>);
+typedef WasmerMemoryDeleteFn = void Function(Pointer<WasmerMemory>);
+
+// wasm_memory_grow
+typedef NativeWasmerMemoryGrowFn = Uint8 Function(
+    Pointer<WasmerMemory>, Uint32);
+typedef WasmerMemoryGrowFn = int Function(Pointer<WasmerMemory>, int);
+
+// wasm_memory_new
+typedef NativeWasmerMemoryNewFn = Pointer<WasmerMemory> Function(
+    Pointer<WasmerStore>, Pointer<WasmerMemorytype>);
+typedef WasmerMemoryNewFn = Pointer<WasmerMemory> Function(
+    Pointer<WasmerStore>, Pointer<WasmerMemorytype>);
+
+// wasm_memory_size
+typedef NativeWasmerMemorySizeFn = Uint32 Function(Pointer<WasmerMemory>);
+typedef WasmerMemorySizeFn = int Function(Pointer<WasmerMemory>);
+
+// wasm_memorytype_delete
+typedef NativeWasmerMemorytypeDeleteFn = Void Function(
+    Pointer<WasmerMemorytype>);
+typedef WasmerMemorytypeDeleteFn = void Function(Pointer<WasmerMemorytype>);
+
+// wasm_memorytype_new
+typedef NativeWasmerMemorytypeNewFn = Pointer<WasmerMemorytype> Function(
+    Pointer<WasmerLimits>);
+typedef WasmerMemorytypeNewFn = Pointer<WasmerMemorytype> Function(
+    Pointer<WasmerLimits>);
+
+// wasm_module_delete
+typedef NativeWasmerModuleDeleteFn = Void Function(Pointer<WasmerModule>);
+typedef WasmerModuleDeleteFn = void Function(Pointer<WasmerModule>);
+
+// wasm_module_exports
+typedef NativeWasmerModuleExportsFn = Void Function(
+    Pointer<WasmerModule>, Pointer<WasmerExporttypeVec>);
+typedef WasmerModuleExportsFn = void Function(
+    Pointer<WasmerModule>, Pointer<WasmerExporttypeVec>);
+
+// wasm_module_imports
+typedef NativeWasmerModuleImportsFn = Void Function(
+    Pointer<WasmerModule>, Pointer<WasmerImporttypeVec>);
+typedef WasmerModuleImportsFn = void Function(
+    Pointer<WasmerModule>, Pointer<WasmerImporttypeVec>);
+
+// wasm_module_new
+typedef NativeWasmerModuleNewFn = Pointer<WasmerModule> Function(
+    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
+typedef WasmerModuleNewFn = Pointer<WasmerModule> Function(
+    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
+
+// wasm_store_delete
+typedef NativeWasmerStoreDeleteFn = Void Function(Pointer<WasmerStore>);
+typedef WasmerStoreDeleteFn = void Function(Pointer<WasmerStore>);
+
+// wasm_store_new
+typedef NativeWasmerStoreNewFn = Pointer<WasmerStore> Function(
+    Pointer<WasmerEngine>);
+typedef WasmerStoreNewFn = Pointer<WasmerStore> Function(Pointer<WasmerEngine>);
+
+// wasm_trap_delete
+typedef NativeWasmerTrapDeleteFn = Void Function(Pointer<WasmerTrap>);
+typedef WasmerTrapDeleteFn = void Function(Pointer<WasmerTrap>);
+
+// wasm_trap_message
+typedef NativeWasmerTrapMessageFn = Void Function(
+    Pointer<WasmerTrap>, Pointer<WasmerByteVec>);
+typedef WasmerTrapMessageFn = void Function(
+    Pointer<WasmerTrap>, Pointer<WasmerByteVec>);
+
+// wasm_trap_new
+typedef NativeWasmerTrapNewFn = Pointer<WasmerTrap> Function(
+    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
+typedef WasmerTrapNewFn = Pointer<WasmerTrap> Function(
+    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
+
+// wasm_valtype_delete
+typedef NativeWasmerValtypeDeleteFn = Void Function(Pointer<WasmerValtype>);
+typedef WasmerValtypeDeleteFn = void Function(Pointer<WasmerValtype>);
+
+// wasm_valtype_kind
+typedef NativeWasmerValtypeKindFn = Uint8 Function(Pointer<WasmerValtype>);
+typedef WasmerValtypeKindFn = int Function(Pointer<WasmerValtype>);
+
+// wasm_valtype_vec_delete
+typedef NativeWasmerValtypeVecDeleteFn = Void Function(
+    Pointer<WasmerValtypeVec>);
+typedef WasmerValtypeVecDeleteFn = void Function(Pointer<WasmerValtypeVec>);
+
+// wasm_valtype_vec_new
+typedef NativeWasmerValtypeVecNewFn = Void Function(
+    Pointer<WasmerValtypeVec>, Uint64, Pointer<Pointer<WasmerValtype>>);
+typedef WasmerValtypeVecNewFn = void Function(
+    Pointer<WasmerValtypeVec>, int, Pointer<Pointer<WasmerValtype>>);
+
+// wasm_valtype_vec_new_empty
+typedef NativeWasmerValtypeVecNewEmptyFn = Void Function(
+    Pointer<WasmerValtypeVec>);
+typedef WasmerValtypeVecNewEmptyFn = void Function(Pointer<WasmerValtypeVec>);
+
+// wasm_valtype_vec_new_uninitialized
+typedef NativeWasmerValtypeVecNewUninitializedFn = Void Function(
+    Pointer<WasmerValtypeVec>, Uint64);
+typedef WasmerValtypeVecNewUninitializedFn = void Function(
+    Pointer<WasmerValtypeVec>, int);
+
+// wasmer_last_error_length
+typedef NativeWasmerWasmerLastErrorLengthFn = Int64 Function();
+typedef WasmerWasmerLastErrorLengthFn = int Function();
+
+// wasmer_last_error_message
+typedef NativeWasmerWasmerLastErrorMessageFn = Int64 Function(
+    Pointer<Uint8>, Int64);
+typedef WasmerWasmerLastErrorMessageFn = int Function(Pointer<Uint8>, int);
diff --git a/pkg/wasm/test/basic_test.dart b/pkg/wasm/test/basic_test.dart
index cd6020e..d222bbe 100644
--- a/pkg/wasm/test/basic_test.dart
+++ b/pkg/wasm/test/basic_test.dart
@@ -23,7 +23,7 @@
 
     var inst = WasmModule(data).instantiate().build();
     var fn = inst.lookupFunction('square');
-    int n = fn(1234);
+    var n = fn(1234) as int;
 
     expect(n, 1234 * 1234);
 
diff --git a/pkg/wasm/test/fn_import_error_test.dart b/pkg/wasm/test/fn_import_error_test.dart
index 5642878..75c69f3 100644
--- a/pkg/wasm/test/fn_import_error_test.dart
+++ b/pkg/wasm/test/fn_import_error_test.dart
@@ -9,6 +9,8 @@
 import 'package:test/test.dart';
 import 'package:wasm/wasm.dart';
 
+import 'test_shared.dart';
+
 void main() {
   test('bad function imports', () {
     // This module expects a function import like:
@@ -29,50 +31,67 @@
     var mod = WasmModule(data);
 
     // Valid instantiation.
-    var inst = mod
+    mod
         .instantiate()
         .addFunction('env', 'someFn', (int a, int b, num c, double d) => 123)
         .build();
 
     // Missing imports.
-    expect(() => mod.instantiate().build(),
-        throwsA(predicate((Exception e) => '$e'.contains('Missing import'))));
+    expect(
+      () => mod.instantiate().build(),
+      throwsExceptionWithToString(contains('Missing import')),
+    );
 
     // Wrong kind of import.
     expect(
-        () =>
-            mod.instantiate().addMemory('env', 'someFn', mod.createMemory(10)),
-        throwsA(predicate(
-            (Exception e) => '$e'.contains('Import is not a memory'))));
+      () => mod.instantiate().addMemory('env', 'someFn', mod.createMemory(10)),
+      throwsExceptionWithToString(
+        contains('Import is not a memory'),
+      ),
+    );
 
     // Wrong namespace.
     expect(
-        () => mod
-            .instantiate()
-            .addFunction(
-                'foo', 'someFn', (int a, int b, num c, double d) => 123)
-            .build(),
-        throwsA(predicate((Exception e) => '$e'.contains('Import not found'))));
+      () => mod
+          .instantiate()
+          .addFunction(
+            'foo',
+            'someFn',
+            (int a, int b, num c, double d) => 123,
+          )
+          .build(),
+      throwsExceptionWithToString(contains('Import not found')),
+    );
 
     // Wrong name.
     expect(
-        () => mod
-            .instantiate()
-            .addFunction(
-                'env', 'otherFn', (int a, int b, num c, double d) => 123)
-            .build(),
-        throwsA(predicate((Exception e) => '$e'.contains('Import not found'))));
+      () => mod
+          .instantiate()
+          .addFunction(
+            'env',
+            'otherFn',
+            (int a, int b, num c, double d) => 123,
+          )
+          .build(),
+      throwsExceptionWithToString(contains('Import not found')),
+    );
 
     // Already filled.
     expect(
-        () => mod
-            .instantiate()
-            .addFunction(
-                'env', 'someFn', (int a, int b, num c, double d) => 123)
-            .addFunction(
-                'env', 'someFn', (int a, int b, num c, double d) => 456)
-            .build(),
-        throwsA(predicate(
-            (Exception e) => '$e'.contains('Import already filled'))));
+      () => mod
+          .instantiate()
+          .addFunction(
+            'env',
+            'someFn',
+            (int a, int b, num c, double d) => 123,
+          )
+          .addFunction(
+            'env',
+            'someFn',
+            (int a, int b, num c, double d) => 456,
+          )
+          .build(),
+      throwsExceptionWithToString(contains('Import already filled')),
+    );
   });
 }
diff --git a/pkg/wasm/test/fn_import_exception_test.dart b/pkg/wasm/test/fn_import_exception_test.dart
index e62d3b1..48d84f2 100644
--- a/pkg/wasm/test/fn_import_exception_test.dart
+++ b/pkg/wasm/test/fn_import_exception_test.dart
@@ -25,26 +25,26 @@
       0x80, 0x80, 0x00, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x0b,
     ]);
 
-    var called_b = false;
+    var calledB = false;
     var thrownException = Exception('Hello exception!');
     var inst = WasmModule(data).instantiate().addFunction('env', 'a', () {
       throw thrownException;
     }).addFunction('env', 'b', () {
-      called_b = true;
+      calledB = true;
     }).build();
     var fn = inst.lookupFunction('fn');
     expect(() => fn(), throwsA(thrownException));
-    expect(called_b, isFalse);
+    expect(calledB, isFalse);
 
-    var called_a = false;
+    var calledA = false;
     inst = WasmModule(data).instantiate().addFunction('env', 'a', () {
-      called_a = true;
+      calledA = true;
     }).addFunction('env', 'b', () {
-      called_b = true;
+      calledB = true;
     }).build();
     fn = inst.lookupFunction('fn');
     fn();
-    expect(called_a, isTrue);
-    expect(called_b, isTrue);
+    expect(calledA, isTrue);
+    expect(calledB, isTrue);
   });
 }
diff --git a/pkg/wasm/test/fn_import_test.dart b/pkg/wasm/test/fn_import_test.dart
index 862983b..7131468 100644
--- a/pkg/wasm/test/fn_import_test.dart
+++ b/pkg/wasm/test/fn_import_test.dart
@@ -23,17 +23,17 @@
       0xc8, 0x03, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0b,
     ]);
 
-    var report_x = -1;
-    var report_y = -1;
+    var reportX = -1;
+    var reportY = -1;
 
     var inst = WasmModule(data).instantiate().addFunction('env', 'report',
         (int x, int y) {
-      report_x = x;
-      report_y = y;
+      reportX = x;
+      reportY = y;
     }).build();
     var fn = inst.lookupFunction('reportStuff');
     fn();
-    expect(123, report_x);
-    expect(456, report_y);
+    expect(123, reportX);
+    expect(456, reportY);
   });
 }
diff --git a/pkg/wasm/test/hello_wasi_test.dart b/pkg/wasm/test/hello_wasi_test.dart
index a4398c8..8317abb 100644
--- a/pkg/wasm/test/hello_wasi_test.dart
+++ b/pkg/wasm/test/hello_wasi_test.dart
@@ -176,6 +176,7 @@
 
     var fn = inst.lookupFunction('_start');
     fn();
+    // TODO: failing on mac https://github.com/dart-lang/sdk/issues/46222
     var out = utf8.decode(await inst.stdout.first);
     expect(out, 'hello, world!\n');
   });
diff --git a/pkg/wasm/test/hello_world_test.dart b/pkg/wasm/test/hello_world_test.dart
index 1f0514c..2ea981f 100644
--- a/pkg/wasm/test/hello_world_test.dart
+++ b/pkg/wasm/test/hello_world_test.dart
@@ -173,8 +173,8 @@
     ]);
 
     late WasmMemory mem;
-    var out = '';
-    var getI32 = (int p) {
+    var out = StringBuffer();
+    int getI32(int p) {
       // Read a little-endian I32.
       var n = 0;
       for (var i = p + 3; i >= p; --i) {
@@ -182,28 +182,29 @@
         n += mem[i];
       }
       return n;
-    };
+    }
+
     var inst = WasmModule(data)
         .instantiate()
         .addFunction('wasi_unstable', 'fd_write',
-            (int fd, int iovs, int iovs_len, int unused) {
+            (int fd, int iovs, int iovsLen, int unused) {
       // iovs points to an array of length iovs_len. Each element is two I32s,
       // a char* and a length.
-      var o = '';
-      for (var i = 0; i < iovs_len; ++i) {
+      var o = StringBuffer();
+      for (var i = 0; i < iovsLen; ++i) {
         var str = getI32(iovs + 8 * i);
         var len = getI32(iovs + 4 + 8 * i);
         for (var j = 0; j < len; ++j) {
-          o += String.fromCharCode(mem[str + j]);
+          o.write(String.fromCharCode(mem[str + j]));
         }
       }
-      out += o;
+      out.write(o.toString());
       return o.length;
     }).build();
     mem = inst.memory;
 
     var fn = inst.lookupFunction('_start');
     fn();
-    expect(out, 'hello, world!\n');
+    expect(out.toString(), 'hello, world!\n');
   });
 }
diff --git a/pkg/wasm/test/numerics_test.dart b/pkg/wasm/test/numerics_test.dart
index b88457d..9ecd3d5 100644
--- a/pkg/wasm/test/numerics_test.dart
+++ b/pkg/wasm/test/numerics_test.dart
@@ -36,16 +36,16 @@
     var addF64 = inst.lookupFunction('addF64');
     var addF32 = inst.lookupFunction('addF32');
 
-    int i64 = addI64(0x123456789ABCDEF, 0xFEDCBA987654321);
+    var i64 = addI64(0x123456789ABCDEF, 0xFEDCBA987654321) as int;
     expect(i64, 0x1111111111111110);
 
-    int i32 = addI32(0xABCDEF, 0xFEDCBA);
+    var i32 = addI32(0xABCDEF, 0xFEDCBA) as int;
     expect(i32, 0x1aaaaa9);
 
-    double f64 = addF64(1234.5678, 8765.4321);
+    var f64 = addF64(1234.5678, 8765.4321) as double;
     expect(f64, closeTo(9999.9999, 1e-6));
 
-    double f32 = addF32(1234.5678, 8765.4321);
+    var f32 = addF32(1234.5678, 8765.4321) as double;
     expect(f32, closeTo(9999.9999, 1e-3));
   });
 }
diff --git a/pkg/wasm/test/test_all.dart b/pkg/wasm/test/test_all.dart
deleted file mode 100644
index edf3850..0000000
--- a/pkg/wasm/test/test_all.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2021, 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:test/test.dart';
-
-import 'basic_test.dart' as basic;
-import 'corrupted_error_test.dart' as corrupted_error;
-import 'fn_call_error_test.dart' as fn_call_error;
-import 'fn_import_error_test.dart' as fn_import_error;
-import 'fn_import_exception_test.dart' as fn_import_exception;
-import 'fn_import_test.dart' as fn_import;
-import 'hello_wasi_test.dart' as hello_wasi;
-import 'hello_world_test.dart' as hello_world;
-import 'memory_error_test.dart' as memory_error;
-import 'memory_test.dart' as memory;
-import 'numerics_test.dart' as numerics;
-import 'void_test.dart' as void_;
-import 'wasi_error_test.dart' as wasi_error;
-
-void main() {
-  group('basic', basic.main);
-  group('corrupted_error', corrupted_error.main);
-  group('fn_call_error', fn_call_error.main);
-  group('fn_import_error', fn_import_error.main);
-  group('fn_import_exception', fn_import_exception.main);
-  group('fn_import', fn_import.main);
-  group('hello_wasi', hello_wasi.main);
-  group('hello_world', hello_world.main);
-  group('memory_error', memory_error.main);
-  group('memory', memory.main);
-  group('numerics', numerics.main);
-  group('void', void_.main);
-  group('wasi_error', wasi_error.main);
-}
diff --git a/pkg/wasm/test/test_shared.dart b/pkg/wasm/test/test_shared.dart
new file mode 100644
index 0000000..af4a3ae
--- /dev/null
+++ b/pkg/wasm/test/test_shared.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, 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:test/test.dart';
+
+Matcher throwsExceptionWithToString(Object matcher) => throwsA(
+      isA<Exception>().having((p0) => p0.toString(), 'toString', matcher),
+    );
diff --git a/pkg/wasm/test/void_test.dart b/pkg/wasm/test/void_test.dart
index 7f082e2..0048515 100644
--- a/pkg/wasm/test/void_test.dart
+++ b/pkg/wasm/test/void_test.dart
@@ -30,7 +30,7 @@
     var setFn = inst.lookupFunction('set');
     var getFn = inst.lookupFunction('get');
     expect(setFn(123, 456), isNull);
-    int n = getFn();
+    var n = getFn() as int;
     expect(n, 123 + 456);
   });
 }
diff --git a/pkg/wasm/test/wasi_error_test.dart b/pkg/wasm/test/wasi_error_test.dart
index d8e7945..47b0fb5 100644
--- a/pkg/wasm/test/wasi_error_test.dart
+++ b/pkg/wasm/test/wasi_error_test.dart
@@ -8,6 +8,8 @@
 import 'package:test/test.dart';
 import 'package:wasm/wasm.dart';
 
+import 'test_shared.dart';
+
 void main() {
   test('wasi error', () {
     // Empty wasm module.
@@ -17,9 +19,11 @@
 
     // Failed to fill WASI imports (the empty module was not built with WASI).
     expect(
-        () => WasmModule(emptyModuleData).instantiate().enableWasi(),
-        throwsA(predicate(
-            (Exception e) => '$e'.contains('Failed to fill WASI imports'))));
+      () => WasmModule(emptyModuleData).instantiate().enableWasi(),
+      throwsExceptionWithToString(
+        contains('Failed to fill WASI imports'),
+      ),
+    );
 
     // Hello world module generated by emscripten+WASI. Exports a function like
     // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
@@ -183,29 +187,37 @@
 
     // Trying to import WASI twice.
     expect(
-        () =>
-            WasmModule(helloWorldData).instantiate().enableWasi().enableWasi(),
-        throwsA(predicate(
-            (Exception e) => '$e'.contains('WASI is already enabled'))));
+      () => WasmModule(helloWorldData).instantiate().enableWasi().enableWasi(),
+      throwsExceptionWithToString(contains('WASI is already enabled')),
+    );
 
     // Missing imports due to not enabling WASI.
-    expect(() => WasmModule(helloWorldData).instantiate().build(),
-        throwsA(predicate((Exception e) => '$e'.contains('Missing import'))));
+    expect(
+      () => WasmModule(helloWorldData).instantiate().build(),
+      throwsExceptionWithToString(contains('Missing import')),
+    );
 
     // Trying to get stdout/stderr without WASI enabled (WASI function import has
     // been manually filled).
     var inst = WasmModule(helloWorldData)
         .instantiate()
-        .addFunction('wasi_unstable', 'fd_write',
-            (int fd, int iovs, int iovs_len, int unused) => 0)
+        .addFunction(
+          'wasi_unstable',
+          'fd_write',
+          (int fd, int iovs, int iovsLen, int unused) => 0,
+        )
         .build();
     expect(
-        () => inst.stdout,
-        throwsA(predicate((Exception e) =>
-            '$e'.contains("Can't capture stdout without WASI enabled"))));
+      () => inst.stdout,
+      throwsExceptionWithToString(
+        contains("Can't capture stdout without WASI enabled"),
+      ),
+    );
     expect(
-        () => inst.stderr,
-        throwsA(predicate((Exception e) =>
-            '$e'.contains("Can't capture stderr without WASI enabled"))));
+      () => inst.stderr,
+      throwsExceptionWithToString(
+        contains("Can't capture stderr without WASI enabled"),
+      ),
+    );
   });
 }
diff --git a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py b/pkg/wasm/tool/generate_ffi_boilerplate.py
similarity index 95%
rename from pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
rename to pkg/wasm/tool/generate_ffi_boilerplate.py
index ac7f12c..05966a0 100755
--- a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
+++ b/pkg/wasm/tool/generate_ffi_boilerplate.py
@@ -11,7 +11,7 @@
 # and runtime.dart.
 
 # Usage:
-# generate_ffi_boilerplate.py && dartfmt -w ../runtime.dart ../wasmer_api.dart
+# ./generate_ffi_boilerplate.py && dart format -owrite ../lib/
 
 import os
 import re
@@ -118,8 +118,8 @@
         for t in sorted(opaqueTypes)
     ]) + '\n\n' + '\n\n'.join([
         vecTypeTemplate % (addPrefix(t), camel(t),
-                           ('Pointer<%s>' if ptr else '%s') % nativeTypeToFfi(
-                               '%s_t' % addPrefix(t)),
+                           ('Pointer<%s>' if ptr else '%s') %
+                           nativeTypeToFfi('%s_t' % addPrefix(t)),
                            (byteVecToStringTemplate if t == 'byte' else ''))
         for t, ptr in sorted(vecTypes.items())
     ]) + '\n' + '\n'.join([
@@ -139,7 +139,7 @@
 
 def getRuntimeLoad():
     return '\n'.join([
-        "    %s = _lib.lookupFunction<NativeWasmer%sFn, Wasmer%sFn>('%s');" %
+        "    %s = _lib.lookupFunction<NativeWasmer%sFn, Wasmer%sFn>('%s',);" %
         (dartFnMembName(name), dartFnTypeName(name), dartFnTypeName(name), name)
         for name, _, _ in getFns()
     ])
@@ -372,17 +372,18 @@
 
 
 def writeFile(filename, content):
-    with open(os.path.abspath(os.path.join(thisDir, '..', filename)), 'w') as f:
+    with open(os.path.abspath(os.path.join(thisDir, '../lib/src', filename)),
+              'w') as f:
         f.write(content)
 
 
-wasmerApiText = readFile('wasmer_api_template.dart')
+wasmerApiText = readFile('wasmer_api_template.dart.t')
 wasmerApiText = wasmerApiText.replace('/* <WASMER_API> */', getWasmerApi())
 wasmerApiText = wasmerApiText.replace('/* <GEN_DOC> */', genDoc)
-writeFile('wasmer_api.dart', wasmerApiText)
+writeFile('wasmer_api.g.dart', wasmerApiText)
 
-runtimeText = readFile('runtime_template.dart')
+runtimeText = readFile('runtime_template.dart.t')
 runtimeText = runtimeText.replace('/* <RUNTIME_MEMB> */', getRuntimeMemb())
 runtimeText = runtimeText.replace('/* <RUNTIME_LOAD> */', getRuntimeLoad())
 runtimeText = runtimeText.replace('/* <GEN_DOC> */', genDoc)
-writeFile('runtime.dart', runtimeText)
+writeFile('runtime.g.dart', runtimeText)
diff --git a/pkg/wasm/tool/runtime_template.dart.t b/pkg/wasm/tool/runtime_template.dart.t
new file mode 100644
index 0000000..6b628fb
--- /dev/null
+++ b/pkg/wasm/tool/runtime_template.dart.t
@@ -0,0 +1,351 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/* <GEN_DOC> */
+
+// ignore_for_file: cascade_invocations
+// ignore_for_file: non_constant_identifier_names
+// ignore_for_file: unused_field
+
+part of 'runtime.dart';
+
+class WasmRuntime {
+  static WasmRuntime? _inst;
+
+  DynamicLibrary _lib;
+  late Pointer<WasmerEngine> _engine;
+  Map<int, _WasmTrapsEntry> traps = {};
+
+/* <RUNTIME_MEMB> */
+
+  factory WasmRuntime() => _inst ??= WasmRuntime._init();
+
+  WasmRuntime._init() : _lib = DynamicLibrary.open(_getLibPath()) {
+/* <RUNTIME_LOAD> */
+
+    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
+      throw Exception('Failed to initialize Dart API');
+    }
+    _engine = _engine_new();
+    _checkNotEqual(_engine, nullptr, 'Failed to initialize Wasm engine.');
+    _set_finalizer_for_engine(this, _engine);
+  }
+
+  Pointer<WasmerStore> newStore(Object owner) {
+    var store = _checkNotEqual(
+      _store_new(_engine),
+      nullptr,
+      'Failed to create Wasm store.',
+    );
+    _set_finalizer_for_store(owner, store);
+    return store;
+  }
+
+  Pointer<WasmerModule> compile(
+    Object owner,
+    Pointer<WasmerStore> store,
+    Uint8List data,
+  ) {
+    var dataPtr = calloc<Uint8>(data.length);
+    for (var i = 0; i < data.length; ++i) {
+      dataPtr[i] = data[i];
+    }
+    var dataVec = calloc<WasmerByteVec>();
+    dataVec.ref.data = dataPtr;
+    dataVec.ref.length = data.length;
+
+    var modulePtr = _module_new(store, dataVec);
+
+    calloc.free(dataPtr);
+    calloc.free(dataVec);
+
+    _checkNotEqual(modulePtr, nullptr, 'Wasm module compile failed.');
+    _set_finalizer_for_module(owner, modulePtr);
+    return modulePtr;
+  }
+
+  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
+    var exportsVec = calloc<WasmerExporttypeVec>();
+    _module_exports(module, exportsVec);
+    var exps = <WasmExportDescriptor>[];
+    for (var i = 0; i < exportsVec.ref.length; ++i) {
+      var exp = exportsVec.ref.data[i];
+      var extern = _exporttype_type(exp);
+      var kind = _externtype_kind(extern);
+      var fnType = kind == WasmerExternKindFunction
+          ? _externtype_as_functype(extern)
+          : nullptr;
+      exps.add(
+        WasmExportDescriptor(
+          kind,
+          _exporttype_name(exp).ref.toString(),
+          fnType,
+        ),
+      );
+    }
+    calloc.free(exportsVec);
+    return exps;
+  }
+
+  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
+    var importsVec = calloc<WasmerImporttypeVec>();
+    _module_imports(module, importsVec);
+    var imps = <WasmImportDescriptor>[];
+    for (var i = 0; i < importsVec.ref.length; ++i) {
+      var imp = importsVec.ref.data[i];
+      var extern = _importtype_type(imp);
+      var kind = _externtype_kind(extern);
+      var fnType = kind == WasmerExternKindFunction
+          ? _externtype_as_functype(extern)
+          : nullptr;
+      imps.add(
+        WasmImportDescriptor(
+          kind,
+          _importtype_module(imp).ref.toString(),
+          _importtype_name(imp).ref.toString(),
+          fnType,
+        ),
+      );
+    }
+    calloc.free(importsVec);
+    return imps;
+  }
+
+  void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
+    if (trap != nullptr) {
+      // There are 2 kinds of trap, and their memory is managed differently.
+      // Traps created in the newTrap method below are stored in the traps map
+      // with a corresponding exception, and their memory is managed using a
+      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
+      // code, and in that case we delete them in this function.
+      var entry = traps[trap.address];
+      if (entry != null) {
+        traps.remove(entry);
+        // ignore: only_throw_errors
+        throw entry.exception;
+      } else {
+        var trapMessage = calloc<WasmerByteVec>();
+        _trap_message(trap, trapMessage);
+        var message = 'Wasm trap when calling $source: ${trapMessage.ref}';
+        _byte_vec_delete(trapMessage);
+        calloc.free(trapMessage);
+        _trap_delete(trap);
+        throw Exception(message);
+      }
+    }
+  }
+
+  Pointer<WasmerInstance> instantiate(
+    Object owner,
+    Pointer<WasmerStore> store,
+    Pointer<WasmerModule> module,
+    Pointer<WasmerExternVec> imports,
+  ) {
+    var trap = calloc<Pointer<WasmerTrap>>();
+    trap.value = nullptr;
+    var inst = _instance_new(store, module, imports, trap);
+    maybeThrowTrap(trap.value, 'module initialization function');
+    calloc.free(trap);
+    _checkNotEqual(inst, nullptr, 'Wasm module instantiation failed.');
+    _set_finalizer_for_instance(owner, inst);
+    return inst;
+  }
+
+  // Clean up the exports after use, with deleteExports.
+  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
+    var exports = calloc<WasmerExternVec>();
+    _instance_exports(instancePtr, exports);
+    return exports;
+  }
+
+  void deleteExports(Pointer<WasmerExternVec> exports) {
+    _extern_vec_delete(exports);
+    calloc.free(exports);
+  }
+
+  int externKind(Pointer<WasmerExtern> extern) => _extern_kind(extern);
+
+  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) =>
+      _extern_as_func(extern);
+
+  Pointer<WasmerExtern> functionToExtern(Pointer<WasmerFunc> func) =>
+      _func_as_extern(func);
+
+  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
+    var types = <int>[];
+    var args = _functype_params(funcType);
+    for (var i = 0; i < args.ref.length; ++i) {
+      types.add(_valtype_kind(args.ref.data[i]));
+    }
+    return types;
+  }
+
+  int getReturnType(Pointer<WasmerFunctype> funcType) {
+    var rets = _functype_results(funcType);
+    if (rets.ref.length == 0) {
+      return WasmerValKindVoid;
+    } else if (rets.ref.length > 1) {
+      throw Exception('Multiple return values are not supported');
+    }
+    return _valtype_kind(rets.ref.data[0]);
+  }
+
+  void call(
+    Pointer<WasmerFunc> func,
+    Pointer<WasmerValVec> args,
+    Pointer<WasmerValVec> results,
+    String source,
+  ) {
+    maybeThrowTrap(_func_call(func, args, results), source);
+  }
+
+  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) =>
+      _extern_as_memory(extern);
+
+  Pointer<WasmerExtern> memoryToExtern(Pointer<WasmerMemory> memory) =>
+      _memory_as_extern(memory);
+
+  Pointer<WasmerMemory> newMemory(
+    Object owner,
+    Pointer<WasmerStore> store,
+    int pages,
+    int? maxPages,
+  ) {
+    var limPtr = calloc<WasmerLimits>();
+    limPtr.ref.min = pages;
+    limPtr.ref.max = maxPages ?? wasm_limits_max_default;
+    var memType = _memorytype_new(limPtr);
+    calloc.free(limPtr);
+    _checkNotEqual(memType, nullptr, 'Failed to create memory type.');
+    _set_finalizer_for_memorytype(owner, memType);
+    var memory = _checkNotEqual(
+      _memory_new(store, memType),
+      nullptr,
+      'Failed to create memory.',
+    );
+    _set_finalizer_for_memory(owner, memory);
+    return memory;
+  }
+
+  void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
+    _checkNotEqual(
+      _memory_grow(memory, deltaPages),
+      0,
+      'Failed to grow memory.',
+    );
+  }
+
+  int memoryLength(Pointer<WasmerMemory> memory) => _memory_size(memory);
+
+  Uint8List memoryView(Pointer<WasmerMemory> memory) =>
+      _memory_data(memory).asTypedList(_memory_data_size(memory));
+
+  Pointer<WasmerFunc> newFunc(
+    Object owner,
+    Pointer<WasmerStore> store,
+    Pointer<WasmerFunctype> funcType,
+    Pointer func,
+    Pointer env,
+    Pointer finalizer,
+  ) {
+    var f = _func_new_with_env(
+      store,
+      funcType,
+      func.cast(),
+      env.cast(),
+      finalizer.cast(),
+    );
+    _checkNotEqual(f, nullptr, 'Failed to create function.');
+    _set_finalizer_for_func(owner, f);
+    return f;
+  }
+
+  Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, Object exception) {
+    var msg = calloc<WasmerByteVec>();
+    msg.ref.data = calloc<Uint8>();
+    msg.ref.data[0] = 0;
+    msg.ref.length = 0;
+    var trap = _trap_new(store, msg);
+    calloc.free(msg.ref.data);
+    calloc.free(msg);
+    _checkNotEqual(trap, nullptr, 'Failed to create trap.');
+    var entry = _WasmTrapsEntry(exception);
+    _set_finalizer_for_trap(entry, trap);
+    traps[trap.address] = entry;
+    return trap;
+  }
+
+  Pointer<WasmerWasiConfig> newWasiConfig() {
+    var name = calloc<Uint8>();
+    name[0] = 0;
+    var config = _wasi_config_new(name);
+    calloc.free(name);
+    return _checkNotEqual(config, nullptr, 'Failed to create WASI config.');
+  }
+
+  void captureWasiStdout(Pointer<WasmerWasiConfig> config) {
+    _wasi_config_inherit_stdout(config);
+  }
+
+  void captureWasiStderr(Pointer<WasmerWasiConfig> config) {
+    _wasi_config_inherit_stderr(config);
+  }
+
+  Pointer<WasmerWasiEnv> newWasiEnv(Pointer<WasmerWasiConfig> config) =>
+      _checkNotEqual(
+        _wasi_env_new(config),
+        nullptr,
+        'Failed to create WASI environment.',
+      );
+
+  void wasiEnvSetMemory(
+    Pointer<WasmerWasiEnv> env,
+    Pointer<WasmerMemory> memory,
+  ) {
+    _wasi_env_set_memory(env, memory);
+  }
+
+  void getWasiImports(
+    Pointer<WasmerStore> store,
+    Pointer<WasmerModule> mod,
+    Pointer<WasmerWasiEnv> env,
+    Pointer<WasmerExternVec> imports,
+  ) {
+    _checkNotEqual(
+      _wasi_get_imports(store, mod, env, imports),
+      0,
+      'Failed to fill WASI imports.',
+    );
+  }
+
+  Stream<List<int>> getWasiStdoutStream(Pointer<WasmerWasiEnv> env) =>
+      Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stdout));
+
+  Stream<List<int>> getWasiStderrStream(Pointer<WasmerWasiEnv> env) =>
+      Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stderr));
+
+  String _getLastError() {
+    var length = _wasmer_last_error_length();
+    var buf = calloc<Uint8>(length);
+    _wasmer_last_error_message(buf, length);
+    var message = utf8.decode(buf.asTypedList(length));
+    calloc.free(buf);
+    return message;
+  }
+
+  T _checkNotEqual<T>(T x, T y, String errorMessage) {
+    if (x == y) {
+      throw Exception('$errorMessage\n${_getLastError()}');
+    }
+    return x;
+  }
+
+  static String getSignatureString(
+    String name,
+    List<int> argTypes,
+    int returnType,
+  ) =>
+      '${wasmerValKindName(returnType)} '
+      "$name(${argTypes.map(wasmerValKindName).join(", ")})";
+}
diff --git a/pkg/wasm/tool/wasmer_api_template.dart.t b/pkg/wasm/tool/wasmer_api_template.dart.t
new file mode 100644
index 0000000..bae678e
--- /dev/null
+++ b/pkg/wasm/tool/wasmer_api_template.dart.t
@@ -0,0 +1,11 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/* <GEN_DOC> */
+
+// ignore_for_file: require_trailing_commas
+
+part of 'wasmer_api.dart';
+
+/* <WASMER_API> */
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 4db752a..f3a26e7 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -4755,8 +4755,8 @@
 
 void _upgradeMap(Map map, ServiceObjectOwner? owner) {
   map.forEach((k, v) {
-    if ((v is Map) && _isServiceMap(v)) {
-      map[k] = owner!.getFromMap(v);
+    if ((v is Map) && owner != null && _isServiceMap(v)) {
+      map[k] = owner.getFromMap(v);
     } else if (v is List) {
       _upgradeList(v, owner);
     } else if (v is Map) {
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 1fe66c5..5ff857b 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     final result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], 'Version');
     expect(result['major'], 3);
-    expect(result['minor'], 45);
+    expect(result['minor'], 46);
     expect(result['_privateMajor'], 0);
     expect(result['_privateMinor'], 0);
   },
diff --git a/runtime/observatory_2/lib/src/service/object.dart b/runtime/observatory_2/lib/src/service/object.dart
index e2acf8a..2baf6d5 100644
--- a/runtime/observatory_2/lib/src/service/object.dart
+++ b/runtime/observatory_2/lib/src/service/object.dart
@@ -4765,7 +4765,7 @@
 
 void _upgradeMap(Map map, ServiceObjectOwner owner) {
   map.forEach((k, v) {
-    if ((v is Map) && _isServiceMap(v)) {
+    if ((v is Map) && owner != null && _isServiceMap(v)) {
       map[k] = owner.getFromMap(v);
     } else if (v is List) {
       _upgradeList(v, owner);
diff --git a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
index bd9d9b1..8090856 100644
--- a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(45));
+    expect(result['minor'], equals(46));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index a880734..56e8f0e 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -527,7 +527,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 56;
+static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
@@ -1072,7 +1072,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
@@ -1607,7 +1607,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 56;
+static constexpr dart::compiler::target::word Script_InstanceSize = 48;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     16;
@@ -2153,7 +2153,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 96;
+static constexpr dart::compiler::target::word Script_InstanceSize = 80;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
@@ -2697,7 +2697,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
-static constexpr dart::compiler::target::word Script_InstanceSize = 64;
+static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
@@ -3242,7 +3242,7 @@
 static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
-static constexpr dart::compiler::target::word Script_InstanceSize = 64;
+static constexpr dart::compiler::target::word Script_InstanceSize = 56;
 static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
     32;
@@ -7062,7 +7062,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 20;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 16;
@@ -7669,7 +7669,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
@@ -8280,7 +8280,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
@@ -10093,7 +10093,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 12;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 16;
@@ -10693,7 +10693,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
@@ -11297,7 +11297,7 @@
 static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
 static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 80;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
 static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
 static constexpr dart::compiler::target::word
     AOT_SingleTargetCache_InstanceSize = 32;
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index db2e2f3..60c679e 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -171,23 +171,24 @@
   }
   char buffer[1024];
   ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  ElideJSONSubstring("objects", buffer, buffer);
   EXPECT_STREQ(
-      "[{\"type\":\"@Instance\","
-      "\"_vmType\":\"null\","
-      "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-      "\"name\":\"Null\"},"
-      "\"kind\":\"Null\","
-      "\"fixedId\":true,"
-      "\"id\":\"objects\\/null\","
-      "\"valueAsString\":\"null\"},"
-      "{\"object_key\":"
-      "{\"type\":\"@Instance\","
-      "\"_vmType\":\"null\","
-      "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-      "\"name\":\"Null\"},"
-      "\"kind\":\"Null\","
-      "\"fixedId\":true,"
-      "\"id\":\"objects\\/null\","
+      "[{\"type\":\"@Instance\",\"_vmType\":\"null\",\"class\":{\"type\":\"@"
+      "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"Null\",\"location\":{"
+      "\"type\":\"SourceLocation\",\"script\":{\"type\":\"@Script\","
+      "\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core\\/null.dart\",\"_"
+      "kind\":\"kernel\"},\"tokenPos\":925,\"endTokenPos\":1165},\"library\":{"
+      "\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\",\"name\":\"dart."
+      "core\",\"uri\":\"dart:core\"}},\"kind\":\"Null\",\"fixedId\":true,"
+      "\"id\":\"\",\"valueAsString\":\"null\"},{\"object_key\":{\"type\":\"@"
+      "Instance\",\"_vmType\":\"null\",\"class\":{\"type\":\"@Class\","
+      "\"fixedId\":true,\"id\":\"\",\"name\":\"Null\",\"location\":{\"type\":"
+      "\"SourceLocation\",\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+      "\"id\":\"\",\"uri\":\"dart:core\\/null.dart\",\"_kind\":\"kernel\"},"
+      "\"tokenPos\":925,\"endTokenPos\":1165},\"library\":{\"type\":\"@"
+      "Library\",\"fixedId\":true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":"
+      "\"dart:core\"}},\"kind\":\"Null\",\"fixedId\":true,\"id\":\"\","
       "\"valueAsString\":\"null\"}}]",
       buffer);
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 2b64b3f..abe44ee 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -11600,10 +11600,6 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-void Script::set_compile_time_constants(const Array& value) const {
-  untag()->set_compile_time_constants(value.ptr());
-}
-
 void Script::set_kernel_program_info(const KernelProgramInfo& info) const {
   untag()->set_kernel_program_info(info.ptr());
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1d513f3c9..d778a53 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4464,11 +4464,6 @@
   // The load time in milliseconds since epoch.
   int64_t load_timestamp() const { return untag()->load_timestamp_; }
 
-  ArrayPtr compile_time_constants() const {
-    return untag()->compile_time_constants();
-  }
-  void set_compile_time_constants(const Array& value) const;
-
   KernelProgramInfoPtr kernel_program_info() const {
     return untag()->kernel_program_info();
   }
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index cc858f5..1c23fa8 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -87,6 +87,13 @@
   const String& scrubbed_name = String::Handle(ScrubbedName());
   const String& vm_name = String::Handle(Name());
   AddNameProperties(&jsobj, scrubbed_name.ToCString(), vm_name.ToCString());
+  const Script& script = Script::Handle(this->script());
+  if (!script.IsNull()) {
+    jsobj.AddLocation(script, token_pos(), end_token_pos());
+  }
+
+  jsobj.AddProperty("library", Object::Handle(library()));
+
   if (ref) {
     return;
   }
@@ -116,11 +123,6 @@
     mix ^= interface_array.At(interface_array.Length() - 1);
     jsobj.AddProperty("mixin", mix);
   }
-  jsobj.AddProperty("library", Object::Handle(library()));
-  const Script& script = Script::Handle(this->script());
-  if (!script.IsNull()) {
-    jsobj.AddLocation(script, token_pos(), end_token_pos());
-  }
   {
     JSONArray interfaces_array(&jsobj, "interfaces");
     Type& interface_type = Type::Handle();
@@ -317,6 +319,12 @@
   jsobj.AddProperty("const", is_const());
   jsobj.AddProperty("_intrinsic", is_intrinsic());
   jsobj.AddProperty("_native", is_native());
+
+  const Script& script = Script::Handle(this->script());
+  if (!script.IsNull()) {
+    jsobj.AddLocation(script, token_pos(), end_token_pos());
+  }
+
   if (ref) {
     return;
   }
@@ -348,11 +356,6 @@
       jsobj.AddProperty("_field", field);
     }
   }
-
-  const Script& script = Script::Handle(this->script());
-  if (!script.IsNull()) {
-    jsobj.AddLocation(script, token_pos(), end_token_pos());
-  }
 }
 
 void FfiTrampolineData::PrintJSONImpl(JSONStream* stream, bool ref) const {
@@ -390,6 +393,12 @@
   jsobj.AddProperty("static", is_static());
   jsobj.AddProperty("final", is_final());
   jsobj.AddProperty("const", is_const());
+
+  const class Script& script = Script::Handle(Script());
+  if (!script.IsNull()) {
+    jsobj.AddLocation(script, token_pos(), end_token_pos());
+  }
+
   if (ref) {
     return;
   }
@@ -416,10 +425,6 @@
   } else {
     jsobj.AddPropertyF("_guardLength", "%" Pd, guarded_list_length());
   }
-  const class Script& script = Script::Handle(Script());
-  if (!script.IsNull()) {
-    jsobj.AddLocation(script, token_pos());
-  }
 }
 
 // See also Dart_ScriptGetTokenInfo.
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 4d2a1fc..6136da2 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4344,8 +4344,16 @@
     Class& cls = Class::Handle(isolate->group()->object_store()->bool_class());
     cls.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
+
     EXPECT_STREQ(
-        "{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"bool\"}",
+        "{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"bool\","
+        "\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":\"@"
+        "Script\","
+        "\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core\\/bool.dart\","
+        "\"_kind\":\"kernel\"},\"tokenPos\":436,\"endTokenPos\":4432},"
+        "\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"dart.core\",\"uri\":\"dart:core\"}}",
         buffer);
   }
   // Function reference
@@ -4359,14 +4367,23 @@
     ASSERT(!func.IsNull());
     func.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Function\",\"fixedId\":true,"
-        "\"id\":\"\",\"name\":\"toString\","
-        "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"bool\"},"
-        "\"_kind\":\"RegularFunction\","
-        "\"static\":false,\"const\":false,"
-        "\"_intrinsic\":false,\"_native\":false}",
+        "{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"toString\",\"owner\":{\"type\":\"@Class\","
+        "\"fixedId\":true,\"id\":\"\",\"name\":\"bool\","
+        "\"location\":{\"type\":\"SourceLocation\","
+        "\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+        "\"id\":\"\",\"uri\":\"dart:core\\/bool.dart\","
+        "\"_kind\":\"kernel\"},\"tokenPos\":436,\"endTokenPos\":4432},"
+        "\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"_kind\":\"RegularFunction\",\"static\":false,\"const\":false,"
+        "\"_intrinsic\":false,\"_native\":false,"
+        "\"location\":{\"type\":\"SourceLocation\","
+        "\"script\":{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+        "\"uri\":\"dart:core\\/bool.dart\",\"_kind\":\"kernel\"},"
+        "\"tokenPos\":4372,\"endTokenPos\":4430}}",
         buffer);
   }
   // Library reference
@@ -4386,15 +4403,17 @@
     JSONStream js;
     Bool::True().PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"Bool\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"bool\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"Bool\","
-        "\"fixedId\":true,"
-        "\"id\":\"objects\\/bool-true\",\"valueAsString\":\"true\"}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"Bool\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"bool\",\"location\":{"
+        "\"type\":\"SourceLocation\",\"script\":{\"type\":\"@Script\","
+        "\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core\\/bool.dart\",\"_"
+        "kind\":\"kernel\"},\"tokenPos\":436,\"endTokenPos\":4432},\"library\":"
+        "{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\",\"name\":\"dart."
+        "core\",\"uri\":\"dart:core\"}},\"identityHashCode\":0,\"kind\":"
+        "\"Bool\",\"fixedId\":true,\"id\":\"objects\\/bool-true\","
+        "\"valueAsString\":\"true\"}",
         buffer);
   }
   // Smi reference
@@ -4404,16 +4423,17 @@
     smi.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("_Smi@", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"Smi\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_Smi\","
-        "\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"Int\","
-        "\"fixedId\":true,"
-        "\"id\":\"objects\\/int-7\",\"valueAsString\":\"7\"}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"Smi\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_Smi\",\"_vmName\":"
+        "\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":"
+        "\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-"
+        "patch\\/integers.dart\",\"_kind\":\"kernel\"},\"tokenPos\":16466,"
+        "\"endTokenPos\":24948},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"identityHashCode\":0,\"kind\":\"Int\",\"fixedId\":true,\"id\":"
+        "\"objects\\/int-7\",\"valueAsString\":\"7\"}",
         buffer);
   }
   // Mint reference
@@ -4423,15 +4443,18 @@
     smi.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_Mint@", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"Mint\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_Mint\",\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"Int\","
-        "\"id\":\"\",\"valueAsString\":\"-9223372036854775808\"}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"Mint\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_Mint\",\"_vmName\":"
+        "\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":"
+        "\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-"
+        "patch\\/integers.dart\",\"_kind\":\"kernel\"},\"tokenPos\":25029,"
+        "\"endTokenPos\":25413},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"identityHashCode\":0,\"kind\":\"Int\",\"id\":\"\",\"valueAsString\":"
+        "\"-9223372036854775808\"}",
         buffer);
   }
   // Double reference
@@ -4441,15 +4464,18 @@
     dub.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_Double@", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"Double\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_Double\",\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"Double\","
-        "\"id\":\"\",\"valueAsString\":\"0.1234\"}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"Double\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_Double\",\"_vmName\":"
+        "\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":"
+        "\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-"
+        "patch\\/double.dart\",\"_kind\":\"kernel\"},\"tokenPos\":248,"
+        "\"endTokenPos\":12248},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"identityHashCode\":0,\"kind\":\"Double\",\"id\":\"\","
+        "\"valueAsString\":\"0.1234\"}",
         buffer);
   }
   // String reference
@@ -4459,15 +4485,18 @@
     str.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_OneByteString@", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"String\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_OneByteString\",\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"String\","
-        "\"id\":\"\",\"length\":2,\"valueAsString\":\"dw\"}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"String\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_OneByteString\",\"_"
+        "vmName\":\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{"
+        "\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-"
+        "patch\\/string_patch.dart\",\"_kind\":\"kernel\"},\"tokenPos\":32310,"
+        "\"endTokenPos\":44332},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"identityHashCode\":0,\"kind\":\"String\",\"id\":\"\",\"length\":2,"
+        "\"valueAsString\":\"dw\"}",
         buffer);
   }
   // Array reference
@@ -4477,15 +4506,17 @@
     array.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_List@", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"Array\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_List\",\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"List\","
-        "\"id\":\"\",\"length\":0}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"Array\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_List\",\"_vmName\":"
+        "\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":"
+        "\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-"
+        "patch\\/array.dart\",\"_kind\":\"kernel\"},\"tokenPos\":248,"
+        "\"endTokenPos\":7758},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"identityHashCode\":0,\"kind\":\"List\",\"id\":\"\",\"length\":0}",
         buffer);
   }
   // GrowableObjectArray reference
@@ -4496,16 +4527,18 @@
     array.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_GrowableList@", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"GrowableObjectArray\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_GrowableList\","
-        "\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"List\","
-        "\"id\":\"\",\"length\":0}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"GrowableObjectArray\",\"class\":"
+        "{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_"
+        "GrowableList\",\"_vmName\":\"\",\"location\":{\"type\":"
+        "\"SourceLocation\",\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+        "\"id\":\"\",\"uri\":\"dart:core-patch\\/growable_array.dart\",\"_"
+        "kind\":\"kernel\"},\"tokenPos\":248,\"endTokenPos\":18485},"
+        "\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
+        "\"name\":\"dart.core\",\"uri\":\"dart:core\"}},\"identityHashCode\":0,"
+        "\"kind\":\"List\",\"id\":\"\",\"length\":0}",
         buffer);
   }
   // LinkedHashMap reference
@@ -4516,15 +4549,18 @@
     array.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_InternalLinkedHashMap@", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"LinkedHashMap\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_InternalLinkedHashMap\",\"_vmName\":\"\"},"
-        "\"identityHashCode\":0,"
-        "\"kind\":\"Map\","
-        "\"id\":\"\","
+        "{\"type\":\"@Instance\",\"_vmType\":\"LinkedHashMap\",\"class\":{"
+        "\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_"
+        "InternalLinkedHashMap\",\"_vmName\":\"\",\"location\":{\"type\":"
+        "\"SourceLocation\",\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+        "\"id\":\"\",\"uri\":\"dart:collection-patch\\/"
+        "compact_hash.dart\",\"_kind\":\"kernel\"},\"tokenPos\":6399,"
+        "\"endTokenPos\":6786},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.collection\",\"uri\":\"dart:"
+        "collection\"}},\"identityHashCode\":0,\"kind\":\"Map\",\"id\":\"\","
         "\"length\":0}",
         buffer);
   }
@@ -4535,12 +4571,17 @@
     tag.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_UserTag@", buffer, buffer);
     EXPECT_SUBSTRING(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"UserTag\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_UserTag\",\"_vmName\":\"\"},"
+        "\"type\":\"@Instance\",\"_vmType\":\"UserTag\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_UserTag\",\"_"
+        "vmName\":\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{"
+        "\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:"
+        "developer-patch\\/profiler.dart\",\"_kind\":\"kernel\"},\"tokenPos\":"
+        "414,\"endTokenPos\":672},\"library\":{\"type\":\"@Library\","
+        "\"fixedId\":true,\"id\":\"\",\"name\":\"dart.developer\",\"uri\":"
+        "\"dart:developer\"}},"
         // Handle non-zero identity hash.
         "\"identityHashCode\":",
         buffer);
@@ -4558,12 +4599,16 @@
     type.PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
     ElideJSONSubstring("objects", buffer, buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     ElideJSONSubstring("_Type@", buffer, buffer);
     EXPECT_SUBSTRING(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"Type\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"_Type\",\"_vmName\":\"\"},"
+        "{\"type\":\"@Instance\",\"_vmType\":\"Type\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_Type\",\"_vmName\":"
+        "\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":"
+        "\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-"
+        "patch\\/type_patch.dart\",\"_kind\":\"kernel\"},\"tokenPos\":493,"
+        "\"endTokenPos\":898},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
         // Handle non-zero identity hash.
         "\"identityHashCode\":",
         buffer);
@@ -4571,7 +4616,12 @@
         "\"kind\":\"Type\","
         "\"fixedId\":true,\"id\":\"\","
         "\"typeClass\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"bool\"},\"name\":\"bool\"}",
+        "\"name\":\"bool\",\"location\":{\"type\":\"SourceLocation\","
+        "\"script\":{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":"
+        "\"dart:core\\/bool.dart\",\"_kind\":\"kernel\"},\"tokenPos\":436,"
+        "\"endTokenPos\":4432},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+        "true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
+        "\"name\":\"bool\"}",
         buffer);
   }
   // Null reference
@@ -4579,15 +4629,16 @@
     JSONStream js;
     Object::null_object().PrintJSON(&js, true);
     ElideJSONSubstring("classes", js.ToCString(), buffer);
+    ElideJSONSubstring("libraries", buffer, buffer);
     EXPECT_STREQ(
-        "{\"type\":\"@Instance\","
-        "\"_vmType\":\"null\","
-        "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-        "\"name\":\"Null\"},"
-        "\"kind\":\"Null\","
-        "\"fixedId\":true,"
-        "\"id\":\"objects\\/null\","
-        "\"valueAsString\":\"null\"}",
+        "{\"type\":\"@Instance\",\"_vmType\":\"null\",\"class\":{\"type\":\"@"
+        "Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"Null\",\"location\":{"
+        "\"type\":\"SourceLocation\",\"script\":{\"type\":\"@Script\","
+        "\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core\\/null.dart\",\"_"
+        "kind\":\"kernel\"},\"tokenPos\":925,\"endTokenPos\":1165},\"library\":"
+        "{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\",\"name\":\"dart."
+        "core\",\"uri\":\"dart:core\"}},\"kind\":\"Null\",\"fixedId\":true,"
+        "\"id\":\"objects\\/null\",\"valueAsString\":\"null\"}",
         buffer);
   }
   // Sentinel reference
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index c3c1017..9955114 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1545,7 +1545,6 @@
   COMPRESSED_POINTER_FIELD(StringPtr, url)
   VISIT_FROM(url)
   COMPRESSED_POINTER_FIELD(StringPtr, resolved_url)
-  COMPRESSED_POINTER_FIELD(ArrayPtr, compile_time_constants)
   COMPRESSED_POINTER_FIELD(TypedDataPtr, line_starts)
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
   COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, constant_coverage)
@@ -1594,11 +1593,11 @@
 #endif
 
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-  int64_t load_timestamp_;
   int32_t kernel_script_index_;
+  int64_t load_timestamp_;
 #else
-  int32_t kernel_script_index_;
   int64_t load_timestamp_;
+  int32_t kernel_script_index_;
 #endif
 };
 
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 629d62b..1b09c40 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -43,7 +43,6 @@
   F(Field, host_offset_or_field_id_)                                           \
   F(Script, url_)                                                              \
   F(Script, resolved_url_)                                                     \
-  F(Script, compile_time_constants_)                                           \
   F(Script, line_starts_)                                                      \
   F(Script, debug_positions_)                                                  \
   F(Script, kernel_program_info_)                                              \
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 0b94d3d..390eee4 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 45
+#define SERVICE_PROTOCOL_MINOR_VERSION 46
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index bfbf657..c0d874a 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.45
+# Dart VM Service Protocol 3.46
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.45_ of the Dart VM Service Protocol. This
+This document describes of _version 3.46_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -1687,6 +1687,12 @@
 class @Class extends @Object {
   // The name of this class.
   string name;
+
+  // The location of this class in the source code.
+  SourceLocation location [optional];
+
+  // The library which contains this class.
+  @Library library;
 }
 ```
 
@@ -1697,6 +1703,12 @@
   // The name of this class.
   string name;
 
+  // The location of this class in the source code.
+  SourceLocation location [optional];
+
+  // The library which contains this class.
+  @Library library;
+
   // The error which occurred during class finalization, if it exists.
   @Error error [optional];
 
@@ -1709,12 +1721,6 @@
   // Are allocations of this class being traced?
   bool traceAllocations;
 
-  // The library which contains this class.
-  @Library library;
-
-  // The location of this class in the source code.
-  SourceLocation location [optional];
-
   // The superclass of this class, if any.
   @Class super [optional];
 
@@ -2298,6 +2304,9 @@
 
   // Is this field static?
   bool static;
+
+  // The location of this field in the source code.
+  SourceLocation location [optional];
 }
 ```
 
@@ -2327,12 +2336,12 @@
   // Is this field static?
   bool static;
 
+  // The location of this field in the source code.
+  SourceLocation location [optional];
+
   // The value of this field, if the field is static. If uninitialized,
   // this will take the value of an uninitialized Sentinel.
   @Instance|Sentinel staticValue [optional];
-
-  // The location of this field in the source code.
-  SourceLocation location [optional];
 }
 ```
 
@@ -2401,6 +2410,9 @@
 
   // Is this function const?
   bool const;
+
+  // The location of this function in the source code.
+  SourceLocation location [optional];
 }
 ```
 
@@ -4038,5 +4050,6 @@
 3.43 | Updated heap snapshot format to include identity hash codes. Added `getAllocationTraces` and `setTraceClassAllocation` RPCs, updated `CpuSample` to include `identityHashCode` and `classId` properties, updated `Class` to include `traceAllocations` property.
 3.44 | Added `identityHashCode` property to `@Instance` and `Instance`.
 3.45 | Added `setBreakpointState` RPC and `BreakpointUpdated` event kind.
+3.46 | Moved `sourceLocation` property into reference types for `Class`, `Field`, and `Function`.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index 9bc1aac..f7314c0 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -501,7 +501,10 @@
       "\"name\":\"helper0\",\"owner\":{\"type\":\"@Library\",\"fixedId\":true,"
       "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"},"
       "\"_kind\":\"RegularFunction\",\"static\":true,\"const\":false,"
-      "\"_intrinsic\":false,\"_native\":false},\"count\":1}]}]}],"
+      "\"_intrinsic\":false,\"_native\":false,\"location\":{\"type\":"
+      "\"SourceLocation\",\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+      "\"id\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\",\"_kind\":\"kernel\"},"
+      "\"tokenPos\":0,\"endTokenPos\":11}},\"count\":1}]}]}],"
 
       // One script in the script table.
       "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
@@ -510,7 +513,7 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(SourceReport_CallSites_PolymorphicCall) {
-  char buffer[1024];
+  char buffer[4096];
   const char* kScript =
       "class Common {\n"
       "  func() {}\n"
@@ -553,27 +556,65 @@
 
       // First receiver: "Common", called twice.
       "{\"receiver\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-      "\"name\":\"Common\"},"
+      "\"name\":\"Common\","
+      "\"location\":{\"type\":\"SourceLocation\","
+      "\"script\":{\"type\":\"@Script\","
+      "\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"file:\\/\\/\\/test-lib\","
+      "\"_kind\":\"kernel\"},\"tokenPos\":0,\"endTokenPos\":27},"
+      "\"library\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"}},"
 
       "\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
       "\"name\":\"func\","
       "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-      "\"name\":\"Common\"},\"_kind\":\"RegularFunction\","
+      "\"name\":\"Common\","
+      "\"location\":{\"type\":\"SourceLocation\","
+      "\"script\":{\"type\":\"@Script\","
+      "\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"file:\\/\\/\\/test-lib\","
+      "\"_kind\":\"kernel\"},\"tokenPos\":0,\"endTokenPos\":27},"
+      "\"library\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"}"
+      "},\"_kind\":\"RegularFunction\","
       "\"static\":false,\"const\":false,\"_intrinsic\":false,"
-      "\"_native\":false},"
+      "\"_native\":false,"
+      "\"location\":{\"type\":\"SourceLocation\","
+      "\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+      "\"id\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\","
+      "\"_kind\":\"kernel\"},\"tokenPos\":17,\"endTokenPos\":25}},"
 
       "\"count\":2},"
 
       // Second receiver: "Uncommon", called once.
       "{\"receiver\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-      "\"name\":\"Uncommon\"},"
+      "\"name\":\"Uncommon\","
+      "\"location\":{\"type\":\"SourceLocation\","
+      "\"script\":{\"type\":\"@Script\","
+      "\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"file:\\/\\/\\/test-lib\","
+      "\"_kind\":\"kernel\"},\"tokenPos\":29,\"endTokenPos\":58},"
+      "\"library\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"}},"
 
       "\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
       "\"name\":\"func\","
       "\"owner\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
-      "\"name\":\"Uncommon\"},\"_kind\":\"RegularFunction\","
+      "\"name\":\"Uncommon\","
+      "\"location\":{\"type\":\"SourceLocation\","
+      "\"script\":{\"type\":\"@Script\","
+      "\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"file:\\/\\/\\/test-lib\","
+      "\"_kind\":\"kernel\"},\"tokenPos\":29,\"endTokenPos\":58},"
+      "\"library\":{\"type\":\"@Library\",\"fixedId\":true,"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"}"
+      "},\"_kind\":\"RegularFunction\","
       "\"static\":false,\"const\":false,\"_intrinsic\":false,"
-      "\"_native\":false},"
+      "\"_native\":false,"
+      "\"location\":{\"type\":\"SourceLocation\","
+      "\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+      "\"id\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\","
+      "\"_kind\":\"kernel\"},\"tokenPos\":48,\"endTokenPos\":56}},"
 
       "\"count\":1}]}]}],"
 
@@ -584,7 +625,7 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(SourceReport_MultipleReports) {
-  char buffer[1024];
+  char buffer[2048];
   const char* kScript =
       "helper0() {}\n"
       "helper1() {}\n"
@@ -614,16 +655,18 @@
       // One range not compiled (helper1).
       "{\"scriptIndex\":0,\"startPos\":13,\"endPos\":24,\"compiled\":false},"
 
-      // One range compiled with one callsite (main).
+      // One range compiled with one callsite (main)m
       "{\"scriptIndex\":0,\"startPos\":26,\"endPos\":48,\"compiled\":true,"
-      "\"callSites\":["
-      "{\"name\":\"helper0\",\"tokenPos\":37,\"cacheEntries\":["
-      "{\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
+      "\"callSites\":[{\"name\":\"helper0\",\"tokenPos\":37,\"cacheEntries\":[{"
+      "\"target\":{\"type\":\"@Function\",\"fixedId\":true,\"id\":\"\","
       "\"name\":\"helper0\",\"owner\":{\"type\":\"@Library\",\"fixedId\":true,"
-      "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"},"
-      "\"_kind\":\"RegularFunction\",\"static\":true,\"const\":false,"
-      "\"_intrinsic\":false,\"_native\":false},\"count\":1}]}],"
-      "\"coverage\":{\"hits\":[26,37],\"misses\":[]}}],"
+      "\"id\":\"\",\"name\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\"},\"_"
+      "kind\":\"RegularFunction\",\"static\":true,\"const\":false,\"_"
+      "intrinsic\":false,\"_native\":false,\"location\":{\"type\":"
+      "\"SourceLocation\",\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
+      "\"id\":\"\",\"uri\":\"file:\\/\\/\\/test-lib\",\"_kind\":\"kernel\"},"
+      "\"tokenPos\":0,\"endTokenPos\":11}},\"count\":1}]}],\"coverage\":{"
+      "\"hits\":[26,37],\"misses\":[]}}],"
 
       // One script in the script table.
       "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
diff --git a/sdk/lib/_internal/js_runtime/lib/late_helper.dart b/sdk/lib/_internal/js_runtime/lib/late_helper.dart
index 14f9b454..ceabcd7 100644
--- a/sdk/lib/_internal/js_runtime/lib/late_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/late_helper.dart
@@ -4,7 +4,7 @@
 
 library _late_helper;
 
-import 'dart:_internal' show LateError;
+import 'dart:_internal' show LateError, createSentinel, isSentinel;
 
 void throwLateFieldADI(String fieldName) => throw LateError.fieldADI(fieldName);
 
@@ -109,3 +109,23 @@
     _value = v;
   }
 }
+
+// Helpers for lowering late instance fields:
+// TODO(fishythefish): Support specialization of sentinels based on type.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:as:trust')
+T _lateReadCheck<T>(Object? value, String name) {
+  if (isSentinel(value)) throw LateError.fieldNI(name);
+  return value as T;
+}
+
+@pragma('dart2js:noInline')
+void _lateWriteOnceCheck(Object? value, String name) {
+  if (!isSentinel(value)) throw LateError.fieldAI(name);
+}
+
+@pragma('dart2js:noInline')
+void _lateInitializeOnceCheck(Object? value, String name) {
+  if (!isSentinel(value)) throw LateError.fieldADI(name);
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart b/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
index f87406b..1708230 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.12
+
 /// Contains error codes that transformed async/async* functions use to
 /// communicate with js_helper functions.
 
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index e2dd66d..6d6de2d 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.12
+
 /// Contains the names of globals that are embedded into the output by the
 /// compiler.
 ///
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index c183861..7305491 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.12
+
 /// Constants and predicates used for encoding and decoding type recipes.
 ///
 /// This library is shared between the compiler and the runtime system.
diff --git a/tests/language/nnbd/late/chained_assignment_test.dart b/tests/language/nnbd/late/chained_assignment_test.dart
index 1ca1c65..d76f68e 100644
--- a/tests/language/nnbd/late/chained_assignment_test.dart
+++ b/tests/language/nnbd/late/chained_assignment_test.dart
@@ -23,82 +23,82 @@
   late int d;
 
   b = a = 1;
-  Expect.equals(a, 1);
-  Expect.equals(b, 1);
+  Expect.equals(1, a);
+  Expect.equals(1, b);
 
   a = b = 2;
-  Expect.equals(a, 2);
-  Expect.equals(b, 2);
+  Expect.equals(2, a);
+  Expect.equals(2, b);
 
   b = foo.x = 3;
-  Expect.equals(foo.x, 3);
-  Expect.equals(b, 3);
+  Expect.equals(3, foo.x);
+  Expect.equals(3, b);
 
   foo.x = b = 4;
-  Expect.equals(foo.x, 4);
-  Expect.equals(b, 4);
+  Expect.equals(4, foo.x);
+  Expect.equals(4, b);
 
   b = foo.y = 5;
-  Expect.equals(foo.y, 5);
-  Expect.equals(b, 5);
+  Expect.equals(5, foo.y);
+  Expect.equals(5, b);
 
   foo.y = b = 6;
-  Expect.equals(foo.y, 6);
-  Expect.equals(b, 6);
+  Expect.equals(6, foo.y);
+  Expect.equals(6, b);
 
   b = c = 7;
-  Expect.equals(b, 7);
-  Expect.equals(c, 7);
+  Expect.equals(7, b);
+  Expect.equals(7, c);
 
   d = b = 8;
-  Expect.equals(b, 8);
-  Expect.equals(d, 8);
+  Expect.equals(8, b);
+  Expect.equals(8, d);
 
   Foo.z = a = 9;
-  Expect.equals(a, 9);
-  Expect.equals(Foo.z, 9);
+  Expect.equals(9, a);
+  Expect.equals(9, Foo.z);
 
   a = Foo.z = 10;
-  Expect.equals(a, 10);
-  Expect.equals(Foo.z, 10);
+  Expect.equals(10, a);
+  Expect.equals(10, Foo.z);
 
   Foo.z = foo.x = 11;
-  Expect.equals(foo.x, 11);
-  Expect.equals(Foo.z, 11);
+  Expect.equals(11, foo.x);
+  Expect.equals(11, Foo.z);
 
   foo.x = Foo.z = 12;
-  Expect.equals(foo.x, 12);
-  Expect.equals(Foo.z, 12);
+  Expect.equals(12, foo.x);
+  Expect.equals(12, Foo.z);
 
   Foo.z = foo.y = 13;
-  Expect.equals(foo.y, 13);
-  Expect.equals(Foo.z, 13);
+  Expect.equals(13, foo.y);
+  Expect.equals(13, Foo.z);
 
   foo.y = Foo.z = 14;
-  Expect.equals(foo.y, 14);
-  Expect.equals(Foo.z, 14);
+  Expect.equals(14, foo.y);
+  Expect.equals(14, Foo.z);
 
   foo.w = a = 15;
-  Expect.equals(a, 15);
-  Expect.equals(foo.w, 15);
+  Expect.equals(15, a);
+  Expect.equals(15, foo.w);
 
   a = foo.w = 16;
-  Expect.equals(a, 16);
-  Expect.equals(foo.w, 16);
+  Expect.equals(16, a);
+  Expect.equals(16, foo.w);
 
   foo.w = foo.x = 17;
-  Expect.equals(foo.x, 17);
-  Expect.equals(foo.w, 17);
+  Expect.equals(17, foo.x);
+  Expect.equals(17, foo.w);
 
   foo.x = foo.w = 18;
-  Expect.equals(foo.x, 18);
-  Expect.equals(foo.w, 18);
+  Expect.equals(18, foo.x);
+  Expect.equals(18, foo.w);
 
   foo.w = foo.y = 19;
-  Expect.equals(foo.y, 19);
-  Expect.equals(foo.w, 19);
+  Expect.equals(19, foo.y);
+  Expect.equals(19, foo.w);
 
   foo.y = foo.w = 20;
-  Expect.equals(foo.y, 20);
-  Expect.equals(foo.w, 20);
+  Expect.equals(20, foo.y);
+  Expect.equals(20, foo.w);
 }
diff --git a/tests/language/nnbd/late/covariant_instance_field_test.dart b/tests/language/nnbd/late/covariant_instance_field_test.dart
new file mode 100644
index 0000000..454aff6
--- /dev/null
+++ b/tests/language/nnbd/late/covariant_instance_field_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, 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:expect/expect.dart';
+
+class Foo {
+  covariant late num a;
+  covariant late final num b;
+}
+
+class Bar extends Foo {
+  @override
+  late int a;
+
+  @override
+  late final int b;
+}
+
+void main() {
+  Foo foo = Foo();
+  foo.a = 0;
+  foo.b = 1;
+  Expect.equals(0, foo.a);
+  Expect.equals(1, foo.b);
+  foo.a = 1.618;
+  Expect.equals(1.618, foo.a);
+
+  Foo bar = Bar();
+  bar.a = 2;
+  bar.b = 3;
+  Expect.equals(2, bar.a);
+  Expect.equals(3, bar.b);
+
+  Expect.throws(() {
+    bar.a = 3.14 as dynamic;
+  });
+}
diff --git a/tests/language/nnbd/late/dynamic_instance_field_test.dart b/tests/language/nnbd/late/dynamic_instance_field_test.dart
new file mode 100644
index 0000000..4556dd6
--- /dev/null
+++ b/tests/language/nnbd/late/dynamic_instance_field_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, 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:expect/expect.dart';
+
+class Foo {
+  late int a;
+  late final int b;
+  late int c = -1;
+  late final int d = -2;
+}
+
+class Bar {
+  final String a = 'a';
+  final String b = 'b';
+  final String c = 'c';
+  final String d = 'd';
+}
+
+void main() {
+  dynamic x = fetch(false);
+  Expect.equals('a', x.a);
+  Expect.equals('b', x.b);
+  Expect.equals('c', x.c);
+  Expect.equals('d', x.d);
+
+  x = fetch(true);
+  Expect.equals(-1, x.c);
+  Expect.equals(-2, x.d);
+
+  x.a = 1;
+  x.b = 2;
+  x.c = 3;
+
+  x = fetch(false);
+  Expect.equals('a', x.a);
+  Expect.equals('b', x.b);
+  Expect.equals('c', x.c);
+  Expect.equals('d', x.d);
+
+  x = fetch(true);
+  Expect.equals(1, x.a);
+  Expect.equals(2, x.b);
+  Expect.equals(3, x.c);
+  Expect.equals(-2, x.d);
+}
+
+final foo = Foo();
+final bar = Bar();
+
+@pragma('dart2js:noInline')
+dynamic fetch(bool getFoo) => getFoo ? foo : bar;
diff --git a/tests/language/nnbd/late/generic_covariant_instance_field_test.dart b/tests/language/nnbd/late/generic_covariant_instance_field_test.dart
new file mode 100644
index 0000000..9aecd30
--- /dev/null
+++ b/tests/language/nnbd/late/generic_covariant_instance_field_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2021, 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:expect/expect.dart';
+
+class Foo<T> {
+  late T a;
+  late final T b;
+}
+
+void main() {
+  Foo<num> foo = Foo<num>();
+  foo.a = 0;
+  foo.b = 1;
+  Expect.equals(0, foo.a);
+  Expect.equals(1, foo.b);
+  foo.a = 1.618;
+  Expect.equals(1.618, foo.a);
+
+  Foo<num> bar = Foo<int>();
+  bar.a = 2;
+  bar.b = 3;
+  Expect.equals(2, bar.a);
+  Expect.equals(3, bar.b);
+
+  Expect.throws(() {
+    bar.a = 3.14;
+  });
+}
diff --git a/tests/language/nnbd/late/instance_field_initializers_test.dart b/tests/language/nnbd/late/instance_field_initializers_test.dart
new file mode 100644
index 0000000..4db6816
--- /dev/null
+++ b/tests/language/nnbd/late/instance_field_initializers_test.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2021, 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:expect/expect.dart';
+
+void main() {
+  testInitializerList();
+  testInitializingFormals();
+}
+
+final List<int> history = [];
+
+int log(int n) {
+  history.add(n);
+  return n;
+}
+
+class Foo {
+  late int a;
+  late final int b;
+  late int c = log(-1);
+  late final int d = log(-2);
+
+  Foo.withC()
+      : a = log(1),
+        b = log(2),
+        c = log(3);
+
+  Foo.withoutC()
+      : a = log(1),
+        b = log(2);
+}
+
+void testInitializerList() {
+  history.clear();
+
+  var foo = Foo.withC();
+  Expect.equals(1, foo.a);
+  Expect.equals(2, foo.b);
+  Expect.equals(3, foo.c);
+  Expect.equals(-2, foo.d);
+
+  foo.a = log(100);
+  Expect.throws(() {
+    foo.b = log(101);
+  });
+  foo.c = log(102);
+
+  Expect.equals(100, foo.a);
+  Expect.equals(2, foo.b);
+  Expect.equals(102, foo.c);
+
+  Expect.listEquals([1, 2, 3, -2, 100, 101, 102], history);
+
+  history.clear();
+
+  foo = Foo.withoutC();
+  Expect.equals(1, foo.a);
+  Expect.equals(2, foo.b);
+  Expect.equals(-1, foo.c);
+  Expect.equals(-2, foo.d);
+
+  foo.a = log(100);
+  Expect.throws(() {
+    foo.b = log(101);
+  });
+  foo.c = log(102);
+
+  Expect.equals(100, foo.a);
+  Expect.equals(2, foo.b);
+  Expect.equals(102, foo.c);
+
+  Expect.listEquals([1, 2, -1, -2, 100, 101, 102], history);
+}
+
+class Bar {
+  late int a;
+  late final int b;
+  late int c = log(-1);
+  late final int d = log(-2);
+
+  Bar.withC(this.a, this.b, this.c);
+
+  Bar.withoutC(this.a, this.b);
+}
+
+void testInitializingFormals() {
+  history.clear();
+
+  var bar = Bar.withC(log(1), log(2), log(3));
+  Expect.equals(1, bar.a);
+  Expect.equals(2, bar.b);
+  Expect.equals(3, bar.c);
+  Expect.equals(-2, bar.d);
+
+  bar.a = log(100);
+  Expect.throws(() {
+    bar.b = log(101);
+  });
+  bar.c = log(102);
+
+  Expect.equals(100, bar.a);
+  Expect.equals(2, bar.b);
+  Expect.equals(102, bar.c);
+
+  Expect.listEquals([1, 2, 3, -2, 100, 101, 102], history);
+
+  history.clear();
+
+  bar = Bar.withoutC(log(1), log(2));
+  Expect.equals(1, bar.a);
+  Expect.equals(2, bar.b);
+  Expect.equals(-1, bar.c);
+  Expect.equals(-2, bar.d);
+
+  bar.a = log(100);
+  Expect.throws(() {
+    bar.b = log(101);
+  });
+  bar.c = log(102);
+
+  Expect.equals(100, bar.a);
+  Expect.equals(2, bar.b);
+  Expect.equals(102, bar.c);
+
+  Expect.listEquals([1, 2, -1, -2, 100, 101, 102], history);
+}
diff --git a/third_party/devtools/update.sh b/third_party/devtools/update.sh
index 077d758..ae3aa49 100755
--- a/third_party/devtools/update.sh
+++ b/third_party/devtools/update.sh
@@ -36,5 +36,6 @@
   -name dart/third_party/flutter/devtools \
   -in cipd_package \
   -install-mode copy \
+  -preserve-writable \
   -tag git_revision:$1
 
diff --git a/tools/VERSION b/tools/VERSION
index f6490ca..298baaf 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 176
+PRERELEASE 177
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 1d078c0..0744088 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3357,6 +3357,14 @@
           ]
         },
         {
+          "name": "analyze pkg/wasm",
+          "script": "out/ReleaseX64/dart-sdk/bin/dart",
+          "arguments": [
+            "analyze",
+            "pkg/wasm"
+          ]
+        },
+        {
           "name": "analyze pkg/dds",
           "script": "out/ReleaseX64/dart-sdk/bin/dart",
           "arguments": [