Version 2.11.0-240.0.dev

Merge commit 'f990e70930fb8b407f5ce80d883f2a3915aa90f8' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/basic.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/basic.dart
new file mode 100644
index 0000000..73cf78d
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/basic.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+const null0 = /*cfe.Null()*/ null;
+const bool0 = /*cfe.Bool(true)*/ true;
+const bool1 = /*cfe.Bool(false)*/ false;
+const string0 = /*cfe.String(foo)*/ 'foo';
+const int0 = /*cfe.Int(0)*/ 0;
+const double0 = /*cfe.Double(0.5)*/ 0.5;
+const symbol0 = /*cfe.Symbol(foo)*/ #foo;
+const symbol1 = const /*cfe.Symbol(foo)*/ Symbol('foo');
+
+main() {
+  print(/*Null()*/ null0);
+  print(/*Bool(true)*/ bool0);
+  print(/*Bool(false)*/ bool1);
+  print(/*String(foo)*/ string0);
+  print(/*Int(0)*/ int0);
+  print(/*Double(0.5)*/ double0);
+  print(
+      /*cfe|analyzer.Symbol(foo)*/
+      /*dart2js.Instance(Symbol,{_name:String(foo))*/
+      symbol0);
+  print(
+      /*cfe|analyzer.Symbol(foo)*/
+      /*dart2js.Instance(Symbol,{_name:String(foo))*/
+      symbol1);
+}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/errors.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/errors.dart
new file mode 100644
index 0000000..a2c10241
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/errors.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+String method() => 'foo';
+
+const String string0 =
+    /*cfe|dart2js.error: Method invocation is not a constant expression.*/
+    method();
+
+main() {
+  print(string0);
+}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/function.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/function.dart
new file mode 100644
index 0000000..cb18ecf
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/function.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+T method1<T>(T t) => t;
+Map<T, S> method2<T, S>(T t, S s) => {t: s};
+
+const function0 = /*cfe.Function(method1)*/ method1;
+
+const int Function(int) instantiation0 =
+    /*cfe.Instantiation(method1<int>)*/ method1;
+
+const Map<String, int> Function(String, int) instantiation1 =
+    /*cfe.Instantiation(method2<String,int>)*/ method2;
+
+main() {
+  print(
+      /*cfe|dart2js.Function(method1)*/
+      /*analyzer.Function(method1,type=T* Function<T>(T*)*)*/
+      function0);
+  print(
+      /*cfe.Instantiation(method1<int>)*/
+      /*dart2js.Instantiation(method1<int*>)*/
+      /*analyzer.Function(method1,type=int* Function(int*)*)*/
+      instantiation0);
+  print(
+      /*cfe.Instantiation(method2<String,int>)*/
+      /*dart2js.Instantiation(method2<String*,int*>)*/
+      /*analyzer.Function(method2,type=Map<String*, int*>* Function(String*, int*)*)*/
+      instantiation1);
+}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/list.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/list.dart
new file mode 100644
index 0000000..aec2913
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/list.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+const list0 = /*cfe.List<dynamic>()*/ [];
+
+// TODO(johnniwinther): This seems like an odd offset for the constant. It
+// should probably be at the start of the type arguments.
+const list1 = <int> /*cfe.List<int>()*/ [];
+
+const List<int> list2 = /*cfe.List<int>()*/ [];
+
+const list3 = /*cfe.List<int>(Int(42))*/ [42];
+
+const list4 = /*cfe.List<int>(Int(42),Int(87))*/ [42, 87];
+
+main() {
+  print(/*analyzer.List<dynamic>*()*/ /*cfe|dart2js.List<dynamic>()*/ list0);
+  print(
+      /*analyzer.List<int*>*()*/ /*cfe.List<int>()*/ /*dart2js.List<int*>()*/ list1);
+  print(
+      /*analyzer.List<int*>*()*/ /*cfe.List<int>()*/ /*dart2js.List<int*>()*/ list2);
+  print(
+      /*analyzer.List<int*>*(Int(42))*/ /*cfe.List<int>(Int(42))*/ /*dart2js.List<int*>(Int(42))*/ list3);
+  print(
+      /*analyzer.List<int*>*(Int(42),Int(87))*/ /*cfe.List<int>(Int(42),Int(87))*/ /*dart2js.List<int*>(Int(42),Int(87))*/ list4);
+}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/map.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/map.dart
new file mode 100644
index 0000000..b3b762e
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/map.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+const map0 = /*cfe.Map<dynamic,dynamic>()*/ {};
+
+// TODO(johnniwinther): This seems like an odd offset for the constant. It
+// should probably be at the start of the type arguments.
+const map1 = <String, int> /*cfe.Map<String,int>()*/ {};
+
+const Map<String, int> map2 = /*cfe.Map<String,int>()*/ {};
+
+const map3 = /*cfe.Map<String,int>(String(foo):Int(42))*/ {'foo': 42};
+
+const map4 = /*cfe.Map<String,int>(String(foo):Int(42),String(bar):Int(87))*/
+    {'foo': 42, 'bar': 87};
+
+main() {
+  print(
+      /*analyzer.Map<dynamic, dynamic>*()*/ /*cfe|dart2js.Map<dynamic,dynamic>()*/ map0);
+  print(
+      /*analyzer.Map<String*, int*>*()*/ /*cfe.Map<String,int>()*/ /*dart2js.Map<String*,int*>()*/ map1);
+  print(
+      /*analyzer.Map<String*, int*>*()*/ /*cfe.Map<String,int>()*/ /*dart2js.Map<String*,int*>()*/ map2);
+  print(
+      /*analyzer.Map<String*, int*>*(String(foo):Int(42))*/ /*cfe.Map<String,int>(String(foo):Int(42))*/ /*dart2js.Map<String*,int*>(String(foo):Int(42))*/ map3);
+  print(
+      /*analyzer.Map<String*, int*>*(String(foo):Int(42),String(bar):Int(87))*/ /*cfe.Map<String,int>(String(foo):Int(42),String(bar):Int(87))*/ /*dart2js.Map<String*,int*>(String(foo):Int(42),String(bar):Int(87))*/ map4);
+}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/marker.options b/pkg/_fe_analyzer_shared/test/constants/data_2/marker.options
new file mode 100644
index 0000000..96fd026
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/marker.options
@@ -0,0 +1,3 @@
+cfe=pkg/front_end/test/id_tests/constant_test.dart
+analyzer=pkg/analyzer/test/id_tests/constant_test.dart
+dart2js=pkg/compiler/test/model/cfe_constant_test.dart
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/set.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/set.dart
new file mode 100644
index 0000000..7c4eed7
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/set.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+// ignore: sdk_version_set_literal
+const Set set0 = /*cfe.Set<dynamic>()*/ {};
+
+// TODO(johnniwinther): This seems like an odd offset for the constant. It
+// should probably be at the start of the type arguments.
+// ignore: sdk_version_set_literal
+const set1 = <int> /*cfe.Set<int>()*/ {};
+
+// ignore: sdk_version_set_literal
+const Set<int> set2 = /*cfe.Set<int>()*/ {};
+
+// ignore: sdk_version_set_literal
+const set3 = /*cfe.Set<int>(Int(42))*/ {42};
+
+// ignore: sdk_version_set_literal
+const set4 = /*cfe.Set<int>(Int(42),Int(87))*/ {42, 87};
+
+main() {
+  print(/*analyzer.Set<dynamic>*()*/ /*cfe|dart2js.Set<dynamic>()*/ set0);
+  print(
+      /*analyzer.Set<int*>*()*/ /*cfe.Set<int>()*/ /*dart2js.Set<int*>()*/ set1);
+  print(
+      /*analyzer.Set<int*>*()*/ /*cfe.Set<int>()*/ /*dart2js.Set<int*>()*/ set2);
+  print(
+      /*analyzer.Set<int*>*(Int(42))*/ /*cfe.Set<int>(Int(42))*/ /*dart2js.Set<int*>(Int(42))*/ set3);
+  print(
+      /*analyzer.Set<int*>*(Int(42),Int(87))*/ /*cfe.Set<int>(Int(42),Int(87))*/ /*dart2js.Set<int*>(Int(42),Int(87))*/ set4);
+}
diff --git a/pkg/_fe_analyzer_shared/test/constants/data_2/type_literals.dart b/pkg/_fe_analyzer_shared/test/constants/data_2/type_literals.dart
new file mode 100644
index 0000000..6754f1c
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/constants/data_2/type_literals.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2019, 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.
+
+// @dart = 2.7
+
+import 'dart:async';
+
+typedef Typedef();
+typedef GenericTypedef<T> = void Function(T);
+typedef GenericFunctionTypedef = void Function<T>(T);
+typedef TypedefWithFutureOr = void Function<T>(FutureOr<T>);
+
+const typedef = /*cfe.TypeLiteral(dynamic Function())*/ Typedef;
+const genericTypedef =
+    /*cfe.TypeLiteral(void Function(dynamic))*/ GenericTypedef;
+const genericFunctionTypedef =
+    /*cfe.TypeLiteral(void Function<T>(T))*/ GenericFunctionTypedef;
+const typedefWithFutureOr =
+    /*cfe.TypeLiteral(void Function<T>(FutureOr<T>))*/ TypedefWithFutureOr;
+const futureOr = /*cfe.TypeLiteral(FutureOr<dynamic>)*/ FutureOr;
+const null_ = /*cfe.TypeLiteral(Null)*/ Null;
+
+main() {
+  print(
+      /*analyzer.TypeLiteral(dynamic Function()*)*/
+      /*cfe.TypeLiteral(dynamic Function())*/
+      /*dart2js.TypeLiteral(()->dynamic)*/
+      typedef);
+
+  print(
+      /*analyzer.TypeLiteral(void Function(dynamic)*)*/
+      /*cfe.TypeLiteral(void Function(dynamic))*/
+      /*dart2js.TypeLiteral((dynamic)->void)*/
+      genericTypedef);
+
+  print(
+      /*analyzer.TypeLiteral(void Function<T>(T*)*)*/
+      /*cfe.TypeLiteral(void Function<T>(T))*/
+      /*dart2js.TypeLiteral((0)->void)*/
+      genericFunctionTypedef);
+
+  print(
+      /*analyzer.TypeLiteral(void Function<T>(FutureOr<T*>*)*)*/
+      /*cfe.TypeLiteral(void Function<T>(FutureOr<T>))*/
+      /*dart2js.TypeLiteral((FutureOr<0>)->void)*/
+      typedefWithFutureOr);
+
+  print(
+      /*analyzer.TypeLiteral(FutureOr<dynamic>*)*/
+      /*cfe.TypeLiteral(FutureOr<dynamic>)*/
+      /*dart2js.TypeLiteral(dynamic)*/
+      futureOr);
+
+  print(
+      /*analyzer.TypeLiteral(Null*)*/
+      /*cfe|dart2js.TypeLiteral(Null)*/
+      null_);
+}
diff --git a/pkg/compiler/test/codegen/codegen_test_helper.dart b/pkg/compiler/test/codegen/codegen_test_helper.dart
index 206f5a1..b07f28a 100644
--- a/pkg/compiler/test/codegen/codegen_test_helper.dart
+++ b/pkg/compiler/test/codegen/codegen_test_helper.dart
@@ -8,6 +8,7 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/closure.dart';
 import 'package:compiler/src/common.dart';
+import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
@@ -32,7 +33,7 @@
       shards: 2,
       directory: 'data',
       skip: skip,
-      options: ['--enable-experiment=non-nullable']);
+      options: ['--enable-experiment=non-nullable', Flags.soundNullSafety]);
 }
 
 runTests2(List<String> args, [int shardIndex]) {
diff --git a/pkg/compiler/test/deferred_loading/data/regress_35311/lib.dart b/pkg/compiler/test/deferred_loading/data/regress_35311/lib.dart
index b7ecf26..3a92bbf 100644
--- a/pkg/compiler/test/deferred_loading/data/regress_35311/lib.dart
+++ b/pkg/compiler/test/deferred_loading/data/regress_35311/lib.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.7
+
 /*class: B:
  class_unit=1{lib},
  type_unit=main{}
diff --git a/pkg/compiler/test/deferred_loading/data/regress_35311/main.dart b/pkg/compiler/test/deferred_loading/data/regress_35311/main.dart
index 9489c7f..d10d45f 100644
--- a/pkg/compiler/test/deferred_loading/data/regress_35311/main.dart
+++ b/pkg/compiler/test/deferred_loading/data/regress_35311/main.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.7
+
 import 'lib.dart' deferred as lib;
 
 /*member: main:member_unit=main{}*/
diff --git a/pkg/compiler/test/end_to_end/user_crash_test.dart b/pkg/compiler/test/end_to_end/user_crash_test.dart
index 3154873..ab7f26f 100644
--- a/pkg/compiler/test/end_to_end/user_crash_test.dart
+++ b/pkg/compiler/test/end_to_end/user_crash_test.dart
@@ -74,7 +74,8 @@
       await runCompiler(
           entryPoint: entryPoint,
           memorySourceFiles: memorySourceFiles,
-          diagnosticHandler: diagnostics);
+          diagnosticHandler: diagnostics,
+          unsafeToTouchSourceFiles: true);
     } catch (e) {
       result.exceptions.add(e);
     }
diff --git a/pkg/compiler/test/equivalence/id_equivalence_helper.dart b/pkg/compiler/test/equivalence/id_equivalence_helper.dart
index 86de213..0a9c8d6 100644
--- a/pkg/compiler/test/equivalence/id_equivalence_helper.dart
+++ b/pkg/compiler/test/equivalence/id_equivalence_helper.dart
@@ -135,7 +135,8 @@
         compiler.stopAfterTypeInference =
             options.contains(stopAfterTypeInference);
       },
-      packageConfig: packageConfig);
+      packageConfig: packageConfig,
+      unsafeToTouchSourceFiles: true);
   if (!result.isSuccess) {
     if (skipFailedCompilations) return null;
     Expect.isTrue(
diff --git a/pkg/compiler/test/helpers/compiler_helper.dart b/pkg/compiler/test/helpers/compiler_helper.dart
index eb7046a..891619f 100644
--- a/pkg/compiler/test/helpers/compiler_helper.dart
+++ b/pkg/compiler/test/helpers/compiler_helper.dart
@@ -26,6 +26,15 @@
 export 'package:compiler/src/util/util.dart';
 export 'output_collector.dart';
 
+String _commonTestPath(bool soundNullSafety) {
+  // Pretend this is a dart2js_native test to allow use of 'native' keyword
+  // and import of private libraries. However, we have to choose the correct
+  // folder to enable / disable  implicit cfe opt out of null safety.
+  return soundNullSafety
+      ? 'sdk/tests/dart2js/native'
+      : 'sdk/tests/dart2js_2/native';
+}
+
 /// Compile [code] and returns either the code for [methodName] or, if
 /// [returnAll] is true, the code for the entire program.
 ///
@@ -63,16 +72,15 @@
   if (enableVariance) {
     options.add('${Flags.enableLanguageExperiments}=variance');
   }
+
   if (soundNullSafety) {
     options.add(Flags.soundNullSafety);
   } else {
     options.add(Flags.noSoundNullSafety);
   }
 
-  // Pretend this is a dart2js_native test to allow use of 'native' keyword
-  // and import of private libraries.
-  String commonTestPath = 'sdk/tests/compiler';
-  Uri entryPoint = Uri.parse('memory:$commonTestPath/dart2js_native/main.dart');
+  String commonTestPath = _commonTestPath(soundNullSafety);
+  Uri entryPoint = Uri.parse('memory:$commonTestPath/main.dart');
 
   Map<String, String> source;
   methodName ??= entry;
@@ -123,10 +131,8 @@
     options.add(Flags.noSoundNullSafety);
   }
 
-  // Pretend this is a dart2js_native test to allow use of 'native' keyword
-  // and import of private libraries.
-  String commonTestPath = 'sdk/tests/compiler';
-  Uri entryPoint = Uri.parse('memory:$commonTestPath/dart2js_native/main.dart');
+  String commonTestPath = _commonTestPath(soundNullSafety);
+  Uri entryPoint = Uri.parse('memory:$commonTestPath/main.dart');
 
   CompilationResult result = await runCompiler(
       entryPoint: entryPoint,
diff --git a/pkg/compiler/test/helpers/memory_compiler.dart b/pkg/compiler/test/helpers/memory_compiler.dart
index 06ddcd9..3a19a1b 100644
--- a/pkg/compiler/test/helpers/memory_compiler.dart
+++ b/pkg/compiler/test/helpers/memory_compiler.dart
@@ -12,6 +12,7 @@
 import 'package:compiler/compiler_new.dart'
     show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
 import 'package:compiler/src/common.dart';
+import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/diagnostics/messages.dart' show Message;
 import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
 import 'package:compiler/src/options.dart' show CompilerOptions;
@@ -89,7 +90,8 @@
     bool showDiagnostics: true,
     Uri librariesSpecificationUri,
     Uri packageConfig,
-    void beforeRun(CompilerImpl compiler)}) async {
+    void beforeRun(CompilerImpl compiler),
+    bool unsafeToTouchSourceFiles: false}) async {
   if (entryPoint == null) {
     entryPoint = Uri.parse('memory:main.dart');
   }
@@ -101,7 +103,8 @@
       options: options,
       showDiagnostics: showDiagnostics,
       librariesSpecificationUri: librariesSpecificationUri,
-      packageConfig: packageConfig);
+      packageConfig: packageConfig,
+      unsafeToTouchSourceFiles: unsafeToTouchSourceFiles);
   if (beforeRun != null) {
     beforeRun(compiler);
   }
@@ -120,7 +123,8 @@
     List<String> options: const <String>[],
     bool showDiagnostics: true,
     Uri librariesSpecificationUri,
-    Uri packageConfig}) {
+    Uri packageConfig,
+    bool unsafeToTouchSourceFiles: false}) {
   retainDataForTesting = true;
   librariesSpecificationUri ??= sdkLibrariesSpecificationUri;
 
@@ -134,8 +138,27 @@
     }
   }
 
+  // Create a local in case we end up cloning memorySourceFiles.
+  Map<String, dynamic> sources = memorySourceFiles;
+
+  // If soundNullSafety is not requested, then we prepend the opt out string to
+  // the memory files.
+  if (!options.contains(Flags.soundNullSafety) && !unsafeToTouchSourceFiles) {
+    // Map may be immutable so copy.
+    sources = {};
+    memorySourceFiles.forEach((k, v) => sources[k] = v);
+    RegExp optOutStr = RegExp(r"\/\/\s*@dart\s*=\s*2\.\d+");
+    for (var key in sources.keys) {
+      if (sources[key] is String && key.endsWith('.dart')) {
+        if (!optOutStr.hasMatch(sources[key])) {
+          sources[key] = '// @dart=2.7\n' + sources[key];
+        }
+      }
+    }
+  }
+
   MemorySourceFileProvider provider;
-  provider = new MemorySourceFileProvider(memorySourceFiles);
+  provider = new MemorySourceFileProvider(sources);
   diagnosticHandler = createCompilerDiagnostics(diagnosticHandler, provider,
       showDiagnostics: showDiagnostics,
       verbose: options.contains('-v') || options.contains('--verbose'));
diff --git a/pkg/compiler/test/inference/data/no_such_method.dart b/pkg/compiler/test/inference/data/no_such_method.dart
index 257f5b3..534e0c7 100644
--- a/pkg/compiler/test/inference/data/no_such_method.dart
+++ b/pkg/compiler/test/inference/data/no_such_method.dart
@@ -1,8 +1,12 @@
+// 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.
+
+// @dart = 2.7
+
 /*member: main:[null]*/
 main() {
   missingGetter();
-
-// @dart = 2.7
   missingMethod();
   closureThroughMissingMethod();
   closureThroughMissingSetter();
diff --git a/pkg/compiler/test/model/cfe_constant_test.dart b/pkg/compiler/test/model/cfe_constant_test.dart
index 160e6491..50abef9 100644
--- a/pkg/compiler/test/model/cfe_constant_test.dart
+++ b/pkg/compiler/test/model/cfe_constant_test.dart
@@ -24,7 +24,7 @@
 main(List<String> args) {
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script
-        .resolve('../../../../pkg/_fe_analyzer_shared/test/constants/data'));
+        .resolve('../../../../pkg/_fe_analyzer_shared/test/constants/data_2'));
     await checkTests<String>(dataDir, new ConstantDataComputer(),
         args: args, testedConfigs: [sharedConfig]);
   });
diff --git a/pkg/compiler/test/sourcemaps/mapping_test.dart b/pkg/compiler/test/sourcemaps/mapping_test.dart
index bbff333..e569599 100644
--- a/pkg/compiler/test/sourcemaps/mapping_test.dart
+++ b/pkg/compiler/test/sourcemaps/mapping_test.dart
@@ -106,7 +106,8 @@
       entryPoint: Uri.parse('memory:main.dart'),
       memorySourceFiles: {'main.dart': test.code},
       outputProvider: collector,
-      options: options);
+      options: options,
+      unsafeToTouchSourceFiles: true);
   Expect.isTrue(compilationResult.isSuccess,
       "Unsuccessful compilation of test:\n${test.code}");
   String sourceMapText = collector.getOutput('', OutputType.sourceMap);
diff --git a/pkg/compiler/test/static_type/data/issue42281.dart b/pkg/compiler/test/static_type/data/issue42281.dart
index 853da41..c8d8fdf 100644
--- a/pkg/compiler/test/static_type/data/issue42281.dart
+++ b/pkg/compiler/test/static_type/data/issue42281.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.7
+
 class Class {
   final Type componentType;
 
diff --git a/pkg/compiler/test/static_type/type_promotion_data/issue42281.dart b/pkg/compiler/test/static_type/type_promotion_data/issue42281.dart
index 56a8cd0..3d9a9da 100644
--- a/pkg/compiler/test/static_type/type_promotion_data/issue42281.dart
+++ b/pkg/compiler/test/static_type/type_promotion_data/issue42281.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.7
+
 class Class {
   final Type componentType;
 
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index 4c9d9a2..315dca1 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -497,6 +497,7 @@
 /// to be produced in the set of expressions that cannot be null by DDC's null
 /// inference.
 Future expectNotNull(String code, String expectedNotNull) async {
+  code = '// @dart = 2.9\n$code';
   var result = await kernelCompile(code);
   var collector = NotNullCollector(result.librariesFromDill);
   result.component.accept(collector);
@@ -525,6 +526,7 @@
 
 /// Given the Dart [code], expects all the expressions inferred to be not-null.
 Future expectAllNotNull(String code) async {
+  code = '// @dart = 2.9\n$code';
   var result = (await kernelCompile(code));
   result.component.accept(ExpectAllNotNull(result.librariesFromDill));
 }
diff --git a/pkg/front_end/test/id_testing/data/declarations.dart b/pkg/front_end/test/id_testing/data/declarations.dart
index 8f00ad4..dfe8054 100644
--- a/pkg/front_end/test/id_testing/data/declarations.dart
+++ b/pkg/front_end/test/id_testing/data/declarations.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.7
+
 /*library: file=main.dart*/
 
 /*member: main:main*/
diff --git a/pkg/front_end/test/id_testing/data/errors.dart b/pkg/front_end/test/id_testing/data/errors.dart
index e58d6c4..c2693b3 100644
--- a/pkg/front_end/test/id_testing/data/errors.dart
+++ b/pkg/front_end/test/id_testing/data/errors.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.7
+
 /*cfe.library: file=main.dart*/
 
 /*cfe.member: main:main*/
diff --git a/pkg/wasm/lib/src/module.dart b/pkg/wasm/lib/src/module.dart
index 349757a..6de1399 100644
--- a/pkg/wasm/lib/src/module.dart
+++ b/pkg/wasm/lib/src/module.dart
@@ -114,6 +114,7 @@
   late List<WasmImportDescriptor> _importDescs;
   Map<String, int> _importIndex;
   late Pointer<Pointer<WasmerExtern>> _imports;
+  Pointer<WasmerWasiEnv> _wasiEnv = nullptr;
 
   WasmInstanceBuilder(this._module) : _importIndex = {} {
     _importDescs = WasmRuntime().importDescriptors(_module._module);
@@ -174,6 +175,21 @@
     return this;
   }
 
+  /// Enable WASI and add the default WASI imports.
+  WasmInstanceBuilder enableWasi(
+      {bool captureStdout = false, bool captureStderr = false}) {
+    if (_wasiEnv != nullptr) {
+      throw Exception("WASI is already enabled.");
+    }
+    var runtime = WasmRuntime();
+    var config = runtime.newWasiConfig();
+    if (captureStdout) runtime.captureWasiStdout(config);
+    if (captureStderr) runtime.captureWasiStderr(config);
+    _wasiEnv = runtime.newWasiEnv(config);
+    runtime.getWasiImports(_module._store, _module._module, _wasiEnv, _imports);
+    return this;
+  }
+
   /// Build the module instance.
   WasmInstance build() {
     for (var i = 0; i < _importDescs.length; ++i) {
@@ -181,7 +197,7 @@
         throw Exception("Missing import: ${_importDescs[i]}");
       }
     }
-    return WasmInstance(_module, _imports);
+    return WasmInstance(_module, _imports, _wasiEnv);
   }
 }
 
@@ -190,9 +206,13 @@
   WasmModule _module;
   Pointer<WasmerInstance> _instance;
   Pointer<WasmerMemory>? _exportedMemory;
+  Pointer<WasmerWasiEnv> _wasiEnv;
+  Stream<List<int>>? _stdout;
+  Stream<List<int>>? _stderr;
   Map<String, WasmFunction> _functions = {};
 
-  WasmInstance(this._module, Pointer<Pointer<WasmerExtern>> imports)
+  WasmInstance(
+      this._module, Pointer<Pointer<WasmerExtern>> imports, this._wasiEnv)
       : _instance = WasmRuntime()
             .instantiate(_module._store, _module._module, imports) {
     var runtime = WasmRuntime();
@@ -210,7 +230,11 @@
             name, f, runtime.getArgTypes(ft), runtime.getReturnType(ft));
       } else if (kind == WasmerExternKindMemory) {
         // WASM currently allows only one memory per module.
-        _exportedMemory = runtime.externToMemory(e);
+        var mem = runtime.externToMemory(e);
+        _exportedMemory = mem;
+        if (_wasiEnv != nullptr) {
+          runtime.wasiEnvSetMemory(_wasiEnv as Pointer<WasmerWasiEnv>, mem);
+        }
       }
     }
   }
@@ -228,6 +252,24 @@
     }
     return WasmMemory._fromExport(_exportedMemory as Pointer<WasmerMemory>);
   }
+
+  /// Returns a stream that reads from stdout. To use this, you must enable WASI
+  /// when instantiating the module, and set captureStdout to true.
+  Stream<List<int>> get stdout {
+    if (_wasiEnv == nullptr) {
+      throw Exception("Can't capture stdout without WASI enabled.");
+    }
+    return _stdout ??= WasmRuntime().getWasiStdoutStream(_wasiEnv);
+  }
+
+  /// Returns a stream that reads from stderr. To use this, you must enable WASI
+  /// when instantiating the module, and set captureStderr to true.
+  Stream<List<int>> get stderr {
+    if (_wasiEnv == nullptr) {
+      throw Exception("Can't capture stderr without WASI enabled.");
+    }
+    return _stderr ??= WasmRuntime().getWasiStderrStream(_wasiEnv);
+  }
 }
 
 /// WasmMemory contains the memory of a WasmInstance.
diff --git a/pkg/wasm/lib/src/runtime.dart b/pkg/wasm/lib/src/runtime.dart
index f390891..e14bda0 100644
--- a/pkg/wasm/lib/src/runtime.dart
+++ b/pkg/wasm/lib/src/runtime.dart
@@ -6,6 +6,7 @@
 // To regenerate the file, use the following command
 // "generate_ffi_boilerplate.py".
 
+import 'dart:async';
 import 'dart:convert';
 import 'dart:ffi';
 import 'dart:io';
@@ -58,6 +59,15 @@
 
   DynamicLibrary _lib;
   late Pointer<WasmerEngine> _engine;
+  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;
@@ -120,11 +130,11 @@
   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() {
-    WasmRuntime inst = _inst ?? WasmRuntime._init();
-    _inst = inst;
-    return inst;
+    return _inst ??= WasmRuntime._init();
   }
 
   static String _getLibName() {
@@ -165,6 +175,29 @@
 
   WasmRuntime._init()
       : _lib = DynamicLibrary.open(path.join(_getLibDir(), _getLibName())) {
+    _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');
@@ -329,6 +362,12 @@
             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');
 
     _engine = _engine_new();
   }
@@ -351,11 +390,7 @@
     free(dataPtr);
     free(dataVec);
 
-    if (modulePtr == nullptr) {
-      throw Exception("Wasm module compile failed");
-    }
-
-    return modulePtr;
+    return _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
   }
 
   List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
@@ -399,12 +434,8 @@
 
   Pointer<WasmerInstance> instantiate(Pointer<WasmerStore> store,
       Pointer<WasmerModule> module, Pointer<Pointer<WasmerExtern>> imports) {
-    var instancePtr = _instance_new(store, module, imports, nullptr);
-    if (instancePtr == nullptr) {
-      throw Exception("Wasm module instantiation failed");
-    }
-
-    return instancePtr;
+    return _checkNotEqual(_instance_new(store, module, imports, nullptr),
+        nullptr, "Wasm module instantiation failed.");
   }
 
   Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
@@ -464,19 +495,13 @@
     limPtr.ref.max = maxPages ?? wasm_limits_max_default;
     var memType = _memorytype_new(limPtr);
     free(limPtr);
-    Pointer<WasmerMemory> memPtr = _memory_new(store, memType);
-
-    if (memPtr == nullptr) {
-      throw Exception("Failed to create memory");
-    }
-    return memPtr;
+    return _checkNotEqual(
+        _memory_new(store, memType), nullptr, "Failed to create memory.");
   }
 
   void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
-    var result = _memory_grow(memory, deltaPages);
-    if (result == 0) {
-      throw Exception("Failed to grow memory");
-    }
+    _checkNotEqual(
+        _memory_grow(memory, deltaPages), 0, "Failed to grow memory.");
   }
 
   int memoryLength(Pointer<WasmerMemory> memory) {
@@ -497,9 +522,89 @@
         store, funcType, func.cast(), env.cast(), finalizer.cast());
   }
 
+  Pointer<WasmerWasiConfig> newWasiConfig() {
+    var name = allocate<Uint8>();
+    name[0] = 0;
+    var config = _wasi_config_new(name);
+    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<Pointer<WasmerExtern>> 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 = allocate<Uint8>(count: length);
+    _wasmer_last_error_message(buf, length);
+    String message = utf8.decode(buf.asTypedList(length));
+    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;
+  Pointer<WasmerWasiEnv> _env;
+  Function _reader;
+  Pointer<Uint8> _buf = allocate<Uint8>(count: _bufferLength);
+  int _length = 0;
+  _WasiStreamIterator(this._env, this._reader) {}
+
+  bool moveNext() {
+    _length = _reader(_env, _buf, _bufferLength);
+    return true;
+  }
+
+  List<int> get current => _buf.asTypedList(_length);
+}
+
+class _WasiStreamIterable extends Iterable<List<int>> {
+  Pointer<WasmerWasiEnv> _env;
+  Function _reader;
+  _WasiStreamIterable(this._env, this._reader) {}
+  @override
+  Iterator<List<int>> get iterator => _WasiStreamIterator(_env, _reader);
+}
diff --git a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py b/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
index 94ed965..906cea5 100755
--- a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
+++ b/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
@@ -33,13 +33,23 @@
     return t
 
 
+def removePrefix(t):
+    assert (t.startswith('wasm_') or t.startswith('wasi_') or
+            t.startswith('wasmer_'))
+    return t[(5 if t.startswith('wasm_') else 0):]
+
+
+def addPrefix(t):
+    if t.startswith('wasi_') or t.startswith('wasmer_'):
+        return t
+    return 'wasm_' + t
+
+
 def getDartType(t, i):
     if t in predefTypes:
-        t = predefTypes[t][i]
-    else:
-        assert (t.startswith('wasm_') and t.endswith('_t'))
-        t = 'Wasmer' + camel(t[5:-2])
-    return t
+        return predefTypes[t][i]
+    assert (t.endswith('_t'))
+    return 'Wasmer' + camel(removePrefix(t[:-2]))
 
 
 def dartArgType(a, i):
@@ -54,13 +64,11 @@
 
 
 def dartFnTypeName(n):
-    assert (n.startswith('wasm_'))
-    return camel(n[5:])
+    return camel(removePrefix(n))
 
 
 def dartFnMembName(n):
-    assert (n.startswith('wasm_'))
-    return n[4:]
+    return '_' + removePrefix(n)
 
 
 def nativeTypeToFfi(n):
@@ -77,10 +85,10 @@
             yield name, retType, args
 
 
-opaqueTypeTemplate = '''// wasm_%s_t
+opaqueTypeTemplate = '''// %s_t
 class Wasmer%s extends Struct {}'''
 
-vecTypeTemplate = '''// wasm_%s_vec_t
+vecTypeTemplate = '''// %s_vec_t
 class Wasmer%sVec extends Struct {
   @Uint64()
   external int length;
@@ -103,12 +111,13 @@
 
 def getWasmerApi():
     return ('\n\n'.join([
-        opaqueTypeTemplate % (t, camel(t)) for t in sorted(opaqueTypes)
+        opaqueTypeTemplate % (addPrefix(t), camel(t))
+        for t in sorted(opaqueTypes)
     ]) + '\n\n' + '\n\n'.join([
-        vecTypeTemplate %
-        (t, camel(t),
-         ('Pointer<%s>' if ptr else '%s') % nativeTypeToFfi('wasm_%s_t' % t),
-         (byteVecToStringTemplate if t == 'byte' else ''))
+        vecTypeTemplate % (addPrefix(t), camel(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([
         fnApiTemplate %
@@ -189,38 +198,41 @@
     retType = parseType(ret)
     args = [parseType(a) for a in argpack.split(',') if len(a.strip()) > 0]
     for _, t in args + [retType]:
-        if t not in predefTypes and t[5:-2] not in opaqueTypes and t[
-                5:-6] not in vecTypes:
+        if t not in predefTypes and removePrefix(
+                t[:-2]) not in opaqueTypes and removePrefix(
+                    t[:-6]) not in vecTypes:
             print('Missing type: ' + t)
     fns.append((name, retType, args))
 
 
 def declareOwn(name):
     opaqueTypes.add(name)
-    addFn('void wasm_%s_delete(wasm_%s_t*)' % (name, name))
+    n = addPrefix(name)
+    addFn('void %s_delete(%s_t*)' % (n, n))
 
 
 def declareVec(name, storePtr):
     vecTypes[name] = storePtr
-    addFn('void wasm_%s_vec_new_empty(wasm_%s_vec_t* out)' % (name, name))
-    addFn('void wasm_%s_vec_new_uninitialized(wasm_%s_vec_t* out, size_t)' %
-          (name, name))
-    addFn('void wasm_%s_vec_new(wasm_%s_vec_t* out, size_t, wasm_%s_t %s[])' %
-          (name, name, name, '*' if storePtr else ''))
-    addFn('void wasm_%s_vec_copy(wasm_%s_vec_t* out, const wasm_%s_vec_t*)' %
-          (name, name, name))
-    addFn('void wasm_%s_vec_delete(wasm_%s_vec_t*)' % (name, name))
+    n = addPrefix(name)
+    addFn('void %s_vec_new_empty(%s_vec_t* out)' % (n, n))
+    addFn('void %s_vec_new_uninitialized(%s_vec_t* out, size_t)' % (n, n))
+    addFn('void %s_vec_new(%s_vec_t* out, size_t, %s_t %s[])' %
+          (n, n, n, '*' if storePtr else ''))
+    addFn('void %s_vec_copy(%s_vec_t* out, const %s_vec_t*)' % (n, n, n))
+    addFn('void %s_vec_delete(%s_vec_t*)' % (n, n))
 
 
 def declareType(name, withCopy=True):
     declareOwn(name)
     declareVec(name, True)
     if withCopy:
-        addFn('wasm_%s_t* wasm_%s_copy(wasm_%s_t*)' % (name, name, name))
+        n = addPrefix(name)
+        addFn('%s_t* %s_copy(%s_t*)' % (n, n, n))
 
 
 predefinedType('void', 'Void', 'void')
 predefinedType('bool', 'Uint8', 'int')
+predefinedType('int', 'Int64', 'int')
 predefinedType('byte_t', 'Uint8', 'int')
 predefinedType('wasm_byte_t', 'Uint8', 'int')
 predefinedType('uint8_t', 'Uint8', 'int')
@@ -228,6 +240,8 @@
 predefinedType('uint32_t', 'Uint32', 'int')
 predefinedType('uint64_t', 'Uint64', 'int')
 predefinedType('size_t', 'Uint64', 'int')
+predefinedType('uintptr_t', 'Uint64', 'int')
+predefinedType('intptr_t', 'Int64', 'int')
 predefinedType('int8_t', 'Int8', 'int')
 predefinedType('int16_t', 'Int16', 'int')
 predefinedType('int32_t', 'Int32', 'int')
@@ -239,6 +253,8 @@
 
 declareOwn('engine')
 declareOwn('store')
+declareOwn('wasi_config')
+declareOwn('wasi_env')
 declareVec('byte', False)
 declareVec('val', False)
 declareType('importtype')
@@ -291,6 +307,16 @@
 WASM_API_EXTERN own wasm_func_t* wasm_func_new_with_env( wasm_store_t*, const wasm_functype_t* type, void* fn, void* env, void *finalizer);
 WASM_API_EXTERN own wasm_trap_t* wasm_func_call(const wasm_func_t*, const wasm_val_t args[], wasm_val_t results[]);
 WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
+wasi_config_t* wasi_config_new(const uint8_t* program_name);
+wasi_env_t* wasi_env_new(wasi_config_t* config);
+bool wasi_get_imports(const wasm_store_t* store, const wasm_module_t* module, const wasi_env_t* wasi_env, wasm_extern_t** imports);
+int wasmer_last_error_message(uint8_t* buffer, int length);
+int wasmer_last_error_length();
+void wasi_env_set_memory(wasi_env_t* env, const wasm_memory_t* memory);
+void wasi_config_inherit_stdout(wasi_config_t* config);
+void wasi_config_inherit_stderr(wasi_config_t* config);
+intptr_t wasi_env_read_stderr(wasi_env_t* env, uint8_t* buffer, uintptr_t buffer_len);
+intptr_t wasi_env_read_stdout(wasi_env_t* env, uint8_t* buffer, uintptr_t buffer_len);
 '''
 for f in rawFns.split('\n'):
     if len(f.strip()) > 0:
@@ -312,6 +338,7 @@
     'wasm_val_vec_new_uninitialized',
     'wasm_valtype_copy',
     'wasm_valtype_vec_copy',
+    'wasi_config_delete',
 }
 
 genDoc = '''// This file has been automatically generated. Please do not edit it manually.
diff --git a/pkg/wasm/lib/src/tools/runtime_template.dart b/pkg/wasm/lib/src/tools/runtime_template.dart
index 280edb5..981da8d 100644
--- a/pkg/wasm/lib/src/tools/runtime_template.dart
+++ b/pkg/wasm/lib/src/tools/runtime_template.dart
@@ -4,6 +4,7 @@
 
 /* <GEN_DOC> */
 
+import 'dart:async';
 import 'dart:convert';
 import 'dart:ffi';
 import 'dart:io';
@@ -59,9 +60,7 @@
 /* <RUNTIME_MEMB> */
 
   factory WasmRuntime() {
-    WasmRuntime inst = _inst ?? WasmRuntime._init();
-    _inst = inst;
-    return inst;
+    return _inst ??= WasmRuntime._init();
   }
 
   static String _getLibName() {
@@ -125,11 +124,7 @@
     free(dataPtr);
     free(dataVec);
 
-    if (modulePtr == nullptr) {
-      throw Exception("Wasm module compile failed");
-    }
-
-    return modulePtr;
+    return _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
   }
 
   List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
@@ -173,12 +168,8 @@
 
   Pointer<WasmerInstance> instantiate(Pointer<WasmerStore> store,
       Pointer<WasmerModule> module, Pointer<Pointer<WasmerExtern>> imports) {
-    var instancePtr = _instance_new(store, module, imports, nullptr);
-    if (instancePtr == nullptr) {
-      throw Exception("Wasm module instantiation failed");
-    }
-
-    return instancePtr;
+    return _checkNotEqual(_instance_new(store, module, imports, nullptr),
+        nullptr, "Wasm module instantiation failed.");
   }
 
   Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
@@ -238,19 +229,13 @@
     limPtr.ref.max = maxPages ?? wasm_limits_max_default;
     var memType = _memorytype_new(limPtr);
     free(limPtr);
-    Pointer<WasmerMemory> memPtr = _memory_new(store, memType);
-
-    if (memPtr == nullptr) {
-      throw Exception("Failed to create memory");
-    }
-    return memPtr;
+    return _checkNotEqual(
+        _memory_new(store, memType), nullptr, "Failed to create memory.");
   }
 
   void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
-    var result = _memory_grow(memory, deltaPages);
-    if (result == 0) {
-      throw Exception("Failed to grow memory");
-    }
+    _checkNotEqual(
+        _memory_grow(memory, deltaPages), 0, "Failed to grow memory.");
   }
 
   int memoryLength(Pointer<WasmerMemory> memory) {
@@ -271,9 +256,89 @@
         store, funcType, func.cast(), env.cast(), finalizer.cast());
   }
 
+  Pointer<WasmerWasiConfig> newWasiConfig() {
+    var name = allocate<Uint8>();
+    name[0] = 0;
+    var config = _wasi_config_new(name);
+    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<Pointer<WasmerExtern>> 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 = allocate<Uint8>(count: length);
+    _wasmer_last_error_message(buf, length);
+    String message = utf8.decode(buf.asTypedList(length));
+    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;
+  Pointer<WasmerWasiEnv> _env;
+  Function _reader;
+  Pointer<Uint8> _buf = allocate<Uint8>(count: _bufferLength);
+  int _length = 0;
+  _WasiStreamIterator(this._env, this._reader) {}
+
+  bool moveNext() {
+    _length = _reader(_env, _buf, _bufferLength);
+    return true;
+  }
+
+  List<int> get current => _buf.asTypedList(_length);
+}
+
+class _WasiStreamIterable extends Iterable<List<int>> {
+  Pointer<WasmerWasiEnv> _env;
+  Function _reader;
+  _WasiStreamIterable(this._env, this._reader) {}
+  @override
+  Iterator<List<int>> get iterator => _WasiStreamIterator(_env, _reader);
+}
diff --git a/pkg/wasm/lib/src/wasmer_api.dart b/pkg/wasm/lib/src/wasmer_api.dart
index 95f244f..c8e55c7 100644
--- a/pkg/wasm/lib/src/wasmer_api.dart
+++ b/pkg/wasm/lib/src/wasmer_api.dart
@@ -157,6 +157,12 @@
 // wasm_valtype_t
 class WasmerValtype extends Struct {}
 
+// wasi_config_t
+class WasmerWasiConfig extends Struct {}
+
+// wasi_env_t
+class WasmerWasiEnv extends Struct {}
+
 // wasm_byte_vec_t
 class WasmerByteVec extends Struct {
   @Uint64()
@@ -208,6 +214,64 @@
   external Pointer<Pointer<WasmerValtype>> data;
 }
 
+// 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<Pointer<WasmerExtern>>);
+typedef WasmerWasiGetImportsFn = int Function(
+    Pointer<WasmerStore>,
+    Pointer<WasmerModule>,
+    Pointer<WasmerWasiEnv>,
+    Pointer<Pointer<WasmerExtern>>);
+
 // wasm_byte_vec_delete
 typedef NativeWasmerByteVecDeleteFn = Void Function(Pointer<WasmerByteVec>);
 typedef WasmerByteVecDeleteFn = void Function(Pointer<WasmerByteVec>);
@@ -548,3 +612,12 @@
     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/tests/lib/wasm/fn_import_error_test.dart b/tests/lib/wasm/fn_import_error_test.dart
index 844c9bf..aeca278 100644
--- a/tests/lib/wasm/fn_import_error_test.dart
+++ b/tests/lib/wasm/fn_import_error_test.dart
@@ -27,25 +27,42 @@
   var mod = WasmModule(data);
 
   // Valid instantiation.
-  var inst = mod.instantiate()
-    .addFunction(
-        "env", "someFn", (int a, int b, num c, double d) => 123).build();
+  var inst = mod
+      .instantiate()
+      .addFunction("env", "someFn", (int a, int b, num c, double d) => 123)
+      .build();
 
   // Missing imports.
-  Expect.throws(() => mod.instantiate().build(), (Exception e) => "$e".contains("Missing import"));
+  Expect.throws(() => mod.instantiate().build(),
+      (Exception e) => "$e".contains("Missing import"));
 
   // Wrong kind of import.
-  Expect.throws(() => mod.instantiate().addMemory("env", "someFn", mod.createMemory(10)), (Exception e) => "$e".contains("Import is not a memory"));
+  Expect.throws(
+      () => mod.instantiate().addMemory("env", "someFn", mod.createMemory(10)),
+      (Exception e) => "$e".contains("Import is not a memory"));
 
   // Wrong namespace.
-  Expect.throws(() => mod.instantiate().addFunction("foo", "someFn", (int a, int b, num c, double d) => 123).build(), (Exception e) => "$e".contains("Import not found"));
+  Expect.throws(
+      () => mod
+          .instantiate()
+          .addFunction("foo", "someFn", (int a, int b, num c, double d) => 123)
+          .build(),
+      (Exception e) => "$e".contains("Import not found"));
 
   // Wrong name.
-  Expect.throws(() => mod.instantiate().addFunction("env", "otherFn", (int a, int b, num c, double d) => 123).build(), (Exception e) => "$e".contains("Import not found"));
+  Expect.throws(
+      () => mod
+          .instantiate()
+          .addFunction("env", "otherFn", (int a, int b, num c, double d) => 123)
+          .build(),
+      (Exception e) => "$e".contains("Import not found"));
 
   // Already filled.
-  Expect.throws(() => 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(), (Exception e) => "$e".contains("Import already filled"));
+  Expect.throws(
+      () => 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(),
+      (Exception e) => "$e".contains("Import already filled"));
 }
diff --git a/tests/lib/wasm/hello_wasi_test.dart b/tests/lib/wasm/hello_wasi_test.dart
new file mode 100644
index 0000000..d862b89
--- /dev/null
+++ b/tests/lib/wasm/hello_wasi_test.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2019, 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.
+
+// Variant of hello_world_test that uses the default WASI imports.
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:wasm/wasm.dart";
+import "dart:convert";
+import "dart:typed_data";
+
+void main() async {
+  asyncStart();
+
+  // Hello world module generated by emscripten+WASI. Exports a function like
+  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
+  var data = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
+    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
+    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
+    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
+    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
+    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
+    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
+    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
+    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
+    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
+    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
+    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
+    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
+    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
+    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
+    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
+    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
+    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
+    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
+    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
+    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
+    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
+    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
+    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
+    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
+    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
+    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
+    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
+    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
+    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
+    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
+    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
+    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
+    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
+    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
+    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
+    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
+    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
+    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
+    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
+    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
+    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
+    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
+    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
+    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
+    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
+    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
+    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
+    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
+    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
+    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
+    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
+    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
+    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
+    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
+    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
+    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
+    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
+    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
+    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
+    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
+    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
+    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
+    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
+    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
+    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
+    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
+    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
+    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
+    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
+    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
+    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
+    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
+    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
+    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
+    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
+    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
+    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
+    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
+    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
+    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
+    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
+    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
+    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
+    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
+    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
+    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
+    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
+    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
+    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
+    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
+    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
+    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
+    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
+    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
+    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
+    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
+    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
+    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
+    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
+    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
+    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
+    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
+    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
+    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
+    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
+    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
+    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
+    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
+    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
+    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
+    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
+    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
+    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
+    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
+    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
+    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
+    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
+    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
+    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
+    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
+    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
+    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
+  ]);
+
+  var inst =
+      WasmModule(data).instantiate().enableWasi(captureStdout: true).build();
+
+  var fn = inst.lookupFunction("_start");
+  fn();
+  var out = utf8.decode(await inst.stdout.first);
+  Expect.equals("hello, world!\n", out);
+  asyncEnd();
+}
diff --git a/tests/lib/wasm/wasi_error_test.dart b/tests/lib/wasm/wasi_error_test.dart
new file mode 100644
index 0000000..8418dad
--- /dev/null
+++ b/tests/lib/wasm/wasi_error_test.dart
@@ -0,0 +1,204 @@
+// Copyright (c) 2019, 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.
+
+// Test the errors that can be thrown by WASI.
+
+import "package:expect/expect.dart";
+import "package:wasm/wasm.dart";
+import "dart:typed_data";
+
+void main() {
+  // Empty wasm module.
+  var emptyModuleData = Uint8List.fromList(
+      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
+
+  // Failed to fill WASI imports (the empty module was not built with WASI).
+  Expect.throws(() => WasmModule(emptyModuleData).instantiate().enableWasi(),
+      (Exception e) => "$e".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)`.
+  var helloWorldData = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
+    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
+    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
+    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
+    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
+    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
+    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
+    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
+    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
+    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
+    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
+    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
+    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
+    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
+    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
+    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
+    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
+    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
+    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
+    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
+    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
+    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
+    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
+    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
+    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
+    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
+    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
+    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
+    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
+    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
+    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
+    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
+    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
+    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
+    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
+    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
+    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
+    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
+    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
+    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
+    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
+    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
+    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
+    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
+    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
+    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
+    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
+    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
+    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
+    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
+    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
+    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
+    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
+    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
+    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
+    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
+    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
+    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
+    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
+    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
+    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
+    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
+    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
+    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
+    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
+    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
+    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
+    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
+    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
+    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
+    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
+    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
+    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
+    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
+    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
+    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
+    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
+    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
+    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
+    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
+    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
+    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
+    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
+    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
+    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
+    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
+    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
+    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
+    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
+    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
+    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
+    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
+    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
+    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
+    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
+    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
+    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
+    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
+    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
+    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
+    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
+    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
+    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
+    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
+    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
+    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
+    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
+    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
+    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
+    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
+    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
+    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
+    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
+    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
+    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
+    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
+    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
+    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
+    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
+    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
+    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
+    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
+    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
+  ]);
+
+  // Trying to import WASI twice.
+  Expect.throws(
+      () => WasmModule(helloWorldData).instantiate().enableWasi().enableWasi(),
+      (Exception e) => "$e".contains("WASI is already enabled"));
+
+  // Missing imports due to not enabling WASI.
+  Expect.throws(() => WasmModule(helloWorldData).instantiate().build(),
+      (Exception e) => "$e".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)
+      .build();
+  Expect.throws(
+      () => inst.stdout,
+      (Exception e) =>
+          "$e".contains("Can't capture stdout without WASI enabled"));
+  Expect.throws(
+      () => inst.stderr,
+      (Exception e) =>
+          "$e".contains("Can't capture stderr without WASI enabled"));
+}
diff --git a/tests/lib_2/wasm/fn_import_error_test.dart b/tests/lib_2/wasm/fn_import_error_test.dart
index 844c9bf..aeca278 100644
--- a/tests/lib_2/wasm/fn_import_error_test.dart
+++ b/tests/lib_2/wasm/fn_import_error_test.dart
@@ -27,25 +27,42 @@
   var mod = WasmModule(data);
 
   // Valid instantiation.
-  var inst = mod.instantiate()
-    .addFunction(
-        "env", "someFn", (int a, int b, num c, double d) => 123).build();
+  var inst = mod
+      .instantiate()
+      .addFunction("env", "someFn", (int a, int b, num c, double d) => 123)
+      .build();
 
   // Missing imports.
-  Expect.throws(() => mod.instantiate().build(), (Exception e) => "$e".contains("Missing import"));
+  Expect.throws(() => mod.instantiate().build(),
+      (Exception e) => "$e".contains("Missing import"));
 
   // Wrong kind of import.
-  Expect.throws(() => mod.instantiate().addMemory("env", "someFn", mod.createMemory(10)), (Exception e) => "$e".contains("Import is not a memory"));
+  Expect.throws(
+      () => mod.instantiate().addMemory("env", "someFn", mod.createMemory(10)),
+      (Exception e) => "$e".contains("Import is not a memory"));
 
   // Wrong namespace.
-  Expect.throws(() => mod.instantiate().addFunction("foo", "someFn", (int a, int b, num c, double d) => 123).build(), (Exception e) => "$e".contains("Import not found"));
+  Expect.throws(
+      () => mod
+          .instantiate()
+          .addFunction("foo", "someFn", (int a, int b, num c, double d) => 123)
+          .build(),
+      (Exception e) => "$e".contains("Import not found"));
 
   // Wrong name.
-  Expect.throws(() => mod.instantiate().addFunction("env", "otherFn", (int a, int b, num c, double d) => 123).build(), (Exception e) => "$e".contains("Import not found"));
+  Expect.throws(
+      () => mod
+          .instantiate()
+          .addFunction("env", "otherFn", (int a, int b, num c, double d) => 123)
+          .build(),
+      (Exception e) => "$e".contains("Import not found"));
 
   // Already filled.
-  Expect.throws(() => 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(), (Exception e) => "$e".contains("Import already filled"));
+  Expect.throws(
+      () => 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(),
+      (Exception e) => "$e".contains("Import already filled"));
 }
diff --git a/tests/lib_2/wasm/hello_wasi_test.dart b/tests/lib_2/wasm/hello_wasi_test.dart
new file mode 100644
index 0000000..d862b89
--- /dev/null
+++ b/tests/lib_2/wasm/hello_wasi_test.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2019, 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.
+
+// Variant of hello_world_test that uses the default WASI imports.
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "package:wasm/wasm.dart";
+import "dart:convert";
+import "dart:typed_data";
+
+void main() async {
+  asyncStart();
+
+  // Hello world module generated by emscripten+WASI. Exports a function like
+  // `void _start()`, and prints using `int fd_write(int, int, int, int)`.
+  var data = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
+    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
+    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
+    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
+    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
+    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
+    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
+    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
+    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
+    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
+    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
+    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
+    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
+    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
+    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
+    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
+    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
+    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
+    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
+    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
+    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
+    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
+    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
+    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
+    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
+    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
+    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
+    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
+    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
+    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
+    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
+    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
+    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
+    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
+    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
+    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
+    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
+    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
+    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
+    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
+    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
+    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
+    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
+    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
+    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
+    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
+    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
+    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
+    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
+    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
+    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
+    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
+    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
+    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
+    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
+    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
+    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
+    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
+    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
+    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
+    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
+    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
+    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
+    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
+    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
+    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
+    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
+    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
+    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
+    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
+    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
+    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
+    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
+    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
+    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
+    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
+    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
+    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
+    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
+    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
+    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
+    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
+    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
+    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
+    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
+    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
+    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
+    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
+    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
+    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
+    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
+    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
+    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
+    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
+    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
+    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
+    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
+    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
+    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
+    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
+    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
+    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
+    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
+    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
+    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
+    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
+    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
+    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
+    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
+    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
+    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
+    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
+    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
+    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
+    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
+    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
+    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
+    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
+    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
+    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
+    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
+    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
+    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
+  ]);
+
+  var inst =
+      WasmModule(data).instantiate().enableWasi(captureStdout: true).build();
+
+  var fn = inst.lookupFunction("_start");
+  fn();
+  var out = utf8.decode(await inst.stdout.first);
+  Expect.equals("hello, world!\n", out);
+  asyncEnd();
+}
diff --git a/tests/lib_2/wasm/wasi_error_test.dart b/tests/lib_2/wasm/wasi_error_test.dart
new file mode 100644
index 0000000..8418dad
--- /dev/null
+++ b/tests/lib_2/wasm/wasi_error_test.dart
@@ -0,0 +1,204 @@
+// Copyright (c) 2019, 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.
+
+// Test the errors that can be thrown by WASI.
+
+import "package:expect/expect.dart";
+import "package:wasm/wasm.dart";
+import "dart:typed_data";
+
+void main() {
+  // Empty wasm module.
+  var emptyModuleData = Uint8List.fromList(
+      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
+
+  // Failed to fill WASI imports (the empty module was not built with WASI).
+  Expect.throws(() => WasmModule(emptyModuleData).instantiate().enableWasi(),
+      (Exception e) => "$e".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)`.
+  var helloWorldData = Uint8List.fromList([
+    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0x09, 0x60,
+    0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f,
+    0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60,
+    0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, 0x60,
+    0x00, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x03, 0x7f, 0x7f, 0x7f,
+    0x00, 0x02, 0x1a, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e,
+    0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72,
+    0x69, 0x74, 0x65, 0x00, 0x01, 0x03, 0x0f, 0x0e, 0x03, 0x04, 0x00, 0x03,
+    0x02, 0x07, 0x05, 0x04, 0x03, 0x06, 0x02, 0x02, 0x08, 0x00, 0x04, 0x05,
+    0x01, 0x70, 0x01, 0x04, 0x04, 0x05, 0x06, 0x01, 0x01, 0x80, 0x02, 0x80,
+    0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0xc0, 0x95, 0xc0, 0x02, 0x0b,
+    0x07, 0x2e, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00,
+    0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,
+    0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x05, 0x04, 0x6d, 0x61, 0x69,
+    0x6e, 0x00, 0x04, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x0b,
+    0x09, 0x09, 0x01, 0x00, 0x41, 0x01, 0x0b, 0x03, 0x08, 0x0e, 0x07, 0x0a,
+    0xae, 0x0c, 0x0e, 0xbf, 0x01, 0x01, 0x05, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x04, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f,
+    0x20, 0x02, 0x05, 0x20, 0x01, 0x10, 0x02, 0x0d, 0x01, 0x20, 0x01, 0x28,
+    0x02, 0x10, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x05, 0x6b, 0x20,
+    0x00, 0x49, 0x04, 0x40, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20, 0x00, 0x20,
+    0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20,
+    0x01, 0x2c, 0x00, 0x4b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21,
+    0x03, 0x03, 0x40, 0x20, 0x03, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02,
+    0x41, 0x7f, 0x6a, 0x22, 0x03, 0x41, 0x80, 0x08, 0x6a, 0x2d, 0x00, 0x00,
+    0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x08, 0x20,
+    0x02, 0x20, 0x01, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x22, 0x03, 0x20,
+    0x02, 0x49, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6b, 0x21, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x02, 0x21, 0x06, 0x0b, 0x20, 0x05, 0x20, 0x04, 0x20,
+    0x00, 0x10, 0x03, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x14, 0x20,
+    0x00, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x06, 0x6a, 0x21, 0x03,
+    0x0b, 0x20, 0x03, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00,
+    0x2d, 0x00, 0x4a, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x3a,
+    0x00, 0x4a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71,
+    0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02, 0x1c, 0x20,
+    0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00,
+    0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x82, 0x04,
+    0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x4f, 0x04, 0x40,
+    0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0x0d, 0x20, 0x00, 0x0f, 0x0b,
+    0x20, 0x00, 0x20, 0x02, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x00, 0x20,
+    0x01, 0x73, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x02,
+    0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b,
+    0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20,
+    0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a,
+    0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02, 0x20, 0x03, 0x4f,
+    0x0d, 0x01, 0x20, 0x02, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x02,
+    0x40, 0x20, 0x03, 0x41, 0x7c, 0x71, 0x22, 0x04, 0x41, 0xc0, 0x00, 0x49,
+    0x0d, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x40, 0x6a, 0x22, 0x05, 0x4b,
+    0x0d, 0x00, 0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36,
+    0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, 0x04,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x14, 0x36, 0x02, 0x14, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x18, 0x36,
+    0x02, 0x18, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, 0x1c,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x36, 0x02, 0x20, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x24, 0x36, 0x02, 0x24, 0x20, 0x02, 0x20, 0x01,
+    0x28, 0x02, 0x28, 0x36, 0x02, 0x28, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02,
+    0x2c, 0x36, 0x02, 0x2c, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x30, 0x36,
+    0x02, 0x30, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x34, 0x36, 0x02, 0x34,
+    0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x38, 0x36, 0x02, 0x38, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x3c, 0x36, 0x02, 0x3c, 0x20, 0x01, 0x41, 0x40,
+    0x6b, 0x21, 0x01, 0x20, 0x02, 0x41, 0x40, 0x6b, 0x22, 0x02, 0x20, 0x05,
+    0x4d, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x4f, 0x0d, 0x01,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,
+    0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a,
+    0x22, 0x02, 0x20, 0x04, 0x49, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20,
+    0x03, 0x41, 0x04, 0x49, 0x04, 0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01,
+    0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x20, 0x00, 0x49, 0x04,
+    0x40, 0x20, 0x00, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x21, 0x02,
+    0x03, 0x40, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02,
+    0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x20, 0x01,
+    0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21,
+    0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x20, 0x04, 0x4d, 0x0d,
+    0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x49, 0x04, 0x40, 0x03, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01,
+    0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x22, 0x02,
+    0x20, 0x03, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x06, 0x00,
+    0x10, 0x0c, 0x41, 0x00, 0x0b, 0x03, 0x00, 0x01, 0x0b, 0x7e, 0x01, 0x03,
+    0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01,
+    0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x10,
+    0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x00, 0x10, 0x02, 0x0d, 0x01, 0x20,
+    0x00, 0x28, 0x02, 0x10, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x28,
+    0x02, 0x14, 0x22, 0x03, 0x20, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x2c,
+    0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x03, 0x41,
+    0x01, 0x6a, 0x36, 0x02, 0x14, 0x20, 0x03, 0x41, 0x0a, 0x3a, 0x00, 0x00,
+    0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0f, 0x6a, 0x41, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d,
+    0x00, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x01, 0x41, 0x10,
+    0x6a, 0x24, 0x00, 0x0b, 0x04, 0x00, 0x42, 0x00, 0x0b, 0x04, 0x00, 0x41,
+    0x00, 0x0b, 0x31, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x21, 0x02, 0x20, 0x02,
+    0x02, 0x7f, 0x20, 0x01, 0x28, 0x02, 0x4c, 0x41, 0x7f, 0x4c, 0x04, 0x40,
+    0x20, 0x02, 0x20, 0x01, 0x10, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x20,
+    0x01, 0x10, 0x01, 0x0b, 0x22, 0x01, 0x46, 0x04, 0x40, 0x20, 0x00, 0x0f,
+    0x0b, 0x20, 0x01, 0x0b, 0x62, 0x01, 0x03, 0x7f, 0x41, 0x80, 0x08, 0x21,
+    0x00, 0x03, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x00,
+    0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02,
+    0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84,
+    0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0xff,
+    0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x00, 0x0c, 0x01, 0x0b,
+    0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x21, 0x02, 0x20, 0x01, 0x41,
+    0x01, 0x6a, 0x22, 0x00, 0x21, 0x01, 0x20, 0x02, 0x0d, 0x00, 0x0b, 0x0b,
+    0x20, 0x00, 0x41, 0x80, 0x08, 0x6b, 0x0b, 0x0c, 0x00, 0x02, 0x7f, 0x41,
+    0x00, 0x41, 0x00, 0x10, 0x04, 0x0b, 0x1a, 0x0b, 0x66, 0x01, 0x02, 0x7f,
+    0x41, 0x90, 0x08, 0x28, 0x02, 0x00, 0x22, 0x00, 0x28, 0x02, 0x4c, 0x41,
+    0x00, 0x4e, 0x04, 0x7f, 0x41, 0x01, 0x05, 0x20, 0x01, 0x0b, 0x1a, 0x02,
+    0x40, 0x41, 0x7f, 0x41, 0x00, 0x10, 0x0a, 0x22, 0x01, 0x20, 0x01, 0x20,
+    0x00, 0x10, 0x09, 0x47, 0x1b, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40,
+    0x20, 0x00, 0x2d, 0x00, 0x4b, 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x20, 0x00,
+    0x28, 0x02, 0x14, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x10, 0x4f, 0x0d,
+    0x00, 0x20, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x14, 0x20,
+    0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x10,
+    0x06, 0x0b, 0x0b, 0x3d, 0x01, 0x01, 0x7f, 0x20, 0x02, 0x04, 0x40, 0x03,
+    0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x80, 0xc0, 0x00, 0x20,
+    0x02, 0x41, 0x80, 0xc0, 0x00, 0x49, 0x1b, 0x22, 0x03, 0x10, 0x03, 0x21,
+    0x00, 0x20, 0x01, 0x41, 0x80, 0x40, 0x6b, 0x21, 0x01, 0x20, 0x00, 0x41,
+    0x80, 0x40, 0x6b, 0x21, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x22, 0x02,
+    0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0xb1, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00,
+    0x41, 0x20, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28,
+    0x02, 0x1c, 0x22, 0x04, 0x36, 0x02, 0x10, 0x20, 0x00, 0x28, 0x02, 0x14,
+    0x21, 0x05, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x1c, 0x20, 0x03, 0x20,
+    0x01, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x05, 0x20, 0x04, 0x6b, 0x22,
+    0x01, 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x21, 0x06, 0x41,
+    0x02, 0x21, 0x05, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x03, 0x40,
+    0x02, 0x40, 0x02, 0x7f, 0x20, 0x06, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02,
+    0x3c, 0x20, 0x01, 0x20, 0x05, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x10, 0x00,
+    0x04, 0x40, 0x20, 0x03, 0x41, 0x7f, 0x36, 0x02, 0x0c, 0x41, 0x7f, 0x0c,
+    0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x0b, 0x22, 0x04, 0x46, 0x04,
+    0x40, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x2c, 0x22, 0x01, 0x36, 0x02,
+    0x1c, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01,
+    0x20, 0x00, 0x28, 0x02, 0x30, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0c,
+    0x01, 0x0b, 0x20, 0x04, 0x41, 0x7f, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41,
+    0x00, 0x36, 0x02, 0x1c, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, 0x10, 0x20,
+    0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00,
+    0x41, 0x00, 0x20, 0x05, 0x41, 0x02, 0x46, 0x0d, 0x00, 0x1a, 0x20, 0x02,
+    0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0b, 0x21, 0x04, 0x20, 0x03, 0x41,
+    0x20, 0x6a, 0x24, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x08,
+    0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x07,
+    0x4b, 0x22, 0x08, 0x1b, 0x22, 0x01, 0x20, 0x04, 0x20, 0x07, 0x41, 0x00,
+    0x20, 0x08, 0x1b, 0x6b, 0x22, 0x07, 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a,
+    0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x20, 0x07,
+    0x6b, 0x36, 0x02, 0x04, 0x20, 0x06, 0x20, 0x04, 0x6b, 0x21, 0x06, 0x20,
+    0x05, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x0c, 0x00, 0x00, 0x0b, 0x00, 0x0b,
+    0x0b, 0x4d, 0x06, 0x00, 0x41, 0x80, 0x08, 0x0b, 0x12, 0x68, 0x65, 0x6c,
+    0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00, 0x00,
+    0x00, 0x18, 0x04, 0x00, 0x41, 0x98, 0x08, 0x0b, 0x01, 0x05, 0x00, 0x41,
+    0xa4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xbc, 0x08, 0x0b, 0x0e, 0x02,
+    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x41, 0xd4, 0x08, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xe3, 0x08,
+    0x0b, 0x05, 0x0a, 0xff, 0xff, 0xff, 0xff,
+  ]);
+
+  // Trying to import WASI twice.
+  Expect.throws(
+      () => WasmModule(helloWorldData).instantiate().enableWasi().enableWasi(),
+      (Exception e) => "$e".contains("WASI is already enabled"));
+
+  // Missing imports due to not enabling WASI.
+  Expect.throws(() => WasmModule(helloWorldData).instantiate().build(),
+      (Exception e) => "$e".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)
+      .build();
+  Expect.throws(
+      () => inst.stdout,
+      (Exception e) =>
+          "$e".contains("Can't capture stdout without WASI enabled"));
+  Expect.throws(
+      () => inst.stderr,
+      (Exception e) =>
+          "$e".contains("Can't capture stderr without WASI enabled"));
+}
diff --git a/tools/VERSION b/tools/VERSION
index 1f5a84d..807baa8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 239
+PRERELEASE 240
 PRERELEASE_PATCH 0
\ No newline at end of file