Version 2.11.0-210.0.dev

Merge commit 'ec7eb450586e571182f95220503201c9971a823d' into 'dev'
diff --git a/pkg/wasm/lib/src/function.dart b/pkg/wasm/lib/src/function.dart
index e9a23c5..4ac694e 100644
--- a/pkg/wasm/lib/src/function.dart
+++ b/pkg/wasm/lib/src/function.dart
@@ -10,43 +10,35 @@
 /// WasmFunction is a callable function from a WasmInstance.
 class WasmFunction {
   String _name;
-  Pointer<WasmerFunc> _func;
+  Pointer<WasmerExportFunc> _func;
   List<int> _argTypes;
   int _returnType;
-  Pointer<WasmerVal> _args;
-  Pointer<WasmerVal> _results;
+  Pointer<WasmerValue> _args;
+  Pointer<WasmerValue> _result;
 
   WasmFunction(this._name, this._func, this._argTypes, this._returnType)
-      : _args = _argTypes.length == 0
-            ? nullptr
-            : allocate<WasmerVal>(count: _argTypes.length),
-        _results =
-            _returnType == WasmerValKindVoid ? nullptr : allocate<WasmerVal>() {
+      : _args = allocate<WasmerValue>(count: _argTypes.length),
+        _result = allocate<WasmerValue>() {
     for (var i = 0; i < _argTypes.length; ++i) {
-      _args[i].kind = _argTypes[i];
+      _args[i].tag = _argTypes[i];
     }
   }
 
-  String toString() {
-    return "${wasmerValKindName(_returnType)} $_name" +
-        "(${_argTypes.map(wasmerValKindName).join(", ")})";
-  }
-
   bool _fillArg(dynamic arg, int i) {
     switch (_argTypes[i]) {
-      case WasmerValKindI32:
+      case WasmerValueTagI32:
         if (arg is! int) return false;
         _args[i].i32 = arg;
         return true;
-      case WasmerValKindI64:
+      case WasmerValueTagI64:
         if (arg is! int) return false;
         _args[i].i64 = arg;
         return true;
-      case WasmerValKindF32:
+      case WasmerValueTagF32:
         if (arg is! num) return false;
         _args[i].f32 = arg;
         return true;
-      case WasmerValKindF64:
+      case WasmerValueTagF64:
         if (arg is! num) return false;
         _args[i].f64 = arg;
         return true;
@@ -56,29 +48,29 @@
 
   dynamic apply(List<dynamic> args) {
     if (args.length != _argTypes.length) {
-      throw ArgumentError("Wrong number arguments for WASM function: $this");
+      throw ArgumentError("Wrong number arguments for WASM function: $_name");
     }
     for (var i = 0; i < args.length; ++i) {
       if (!_fillArg(args[i], i)) {
-        throw ArgumentError("Bad argument type for WASM function: $this");
+        throw ArgumentError("Bad argument type for WASM function: $_name");
       }
     }
-    WasmRuntime().call(_func, _args, _results);
+    WasmRuntime().call(_func, _args, _argTypes.length, _result,
+        _returnType == WasmerValueTagVoid ? 0 : 1);
 
-    if (_returnType == WasmerValKindVoid) {
+    if (_returnType == WasmerValueTagVoid) {
       return null;
     }
-    var result = _results[0];
-    assert(_returnType == result.kind);
+    assert(_returnType == _result.ref.tag);
     switch (_returnType) {
-      case WasmerValKindI32:
-        return result.i32;
-      case WasmerValKindI64:
-        return result.i64;
-      case WasmerValKindF32:
-        return result.f32;
-      case WasmerValKindF64:
-        return result.f64;
+      case WasmerValueTagI32:
+        return _result.ref.i32;
+      case WasmerValueTagI64:
+        return _result.ref.i64;
+      case WasmerValueTagF32:
+        return _result.ref.f32;
+      case WasmerValueTagF64:
+        return _result.ref.f64;
     }
   }
 
diff --git a/pkg/wasm/lib/src/module.dart b/pkg/wasm/lib/src/module.dart
index a2a9944..4013966 100644
--- a/pkg/wasm/lib/src/module.dart
+++ b/pkg/wasm/lib/src/module.dart
@@ -11,23 +11,14 @@
 
 /// WasmModule is a compiled module that can be instantiated.
 class WasmModule {
-  Pointer<WasmerStore> _store;
-  late Pointer<WasmerModule> _module;
+  Pointer<WasmerModule> _module;
 
   /// Compile a module.
-  WasmModule(Uint8List data) : _store = WasmRuntime().newStore() {
-    _module = WasmRuntime().compile(_store, data);
-  }
+  WasmModule(Uint8List data) : _module = WasmRuntime().compile(data) {}
 
   /// Instantiate the module with the given imports.
   WasmInstance instantiate(WasmImports imports) {
-    return WasmInstance(_store, _module, imports);
-  }
-
-  /// Create a new memory with the given number of initial pages, and optional
-  /// maximum number of pages.
-  WasmMemory createMemory(int pages, [int? maxPages]) {
-    return WasmMemory._create(_store, pages, maxPages);
+    return WasmInstance(_module, imports);
   }
 
   /// Returns a description of all of the module's imports and exports, for
@@ -37,12 +28,12 @@
     var runtime = WasmRuntime();
     var imports = runtime.importDescriptors(_module);
     for (var imp in imports) {
-      var kind = wasmerExternKindName(imp.kind);
+      var kind = wasmerImpExpKindName(imp.kind);
       description.write('import $kind: ${imp.moduleName}::${imp.name}\n');
     }
     var exports = runtime.exportDescriptors(_module);
     for (var exp in exports) {
-      var kind = wasmerExternKindName(exp.kind);
+      var kind = wasmerImpExpKindName(exp.kind);
       description.write('export $kind: ${exp.name}\n');
     }
     return description.toString();
@@ -51,13 +42,13 @@
 
 /// WasmImports holds all the imports for a WasmInstance.
 class WasmImports {
-  Pointer<Pointer<WasmerExtern>> _imports;
+  Pointer<WasmerImport> _imports;
   int _capacity;
   int _length;
 
   /// Create an imports object.
   WasmImports([this._capacity = 4])
-      : _imports = allocate<Pointer<WasmerExtern>>(count: _capacity),
+      : _imports = allocate<WasmerImport>(count: _capacity),
         _length = 0 {}
 
   /// Returns the number of imports.
@@ -66,31 +57,26 @@
 
 /// WasmInstance is an instantiated WasmModule.
 class WasmInstance {
-  Pointer<WasmerStore> _store;
   Pointer<WasmerModule> _module;
   Pointer<WasmerInstance> _instance;
   Pointer<WasmerMemory>? _exportedMemory;
   Map<String, WasmFunction> _functions = {};
 
-  WasmInstance(this._store, this._module, WasmImports imports)
+  WasmInstance(this._module, WasmImports imports)
       : _instance = WasmRuntime()
-            .instantiate(_store, _module, imports._imports, imports.length) {
+            .instantiate(_module, imports._imports, imports.length) {
     var runtime = WasmRuntime();
-    var exports = runtime.exports(_instance);
-    var exportDescs = runtime.exportDescriptors(_module);
-    assert(exports.ref.length == exportDescs.length);
-    for (var i = 0; i < exports.ref.length; ++i) {
-      var e = exports.ref.data[i];
-      var kind = runtime.externKind(exports.ref.data[i]);
-      String name = exportDescs[i].name;
-      if (kind == WasmerExternKindFunction) {
-        var f = runtime.externToFunction(e);
-        var ft = exportDescs[i].funcType;
+    var exps = runtime.exports(_instance);
+    for (var e in exps) {
+      var kind = runtime.exportKind(e);
+      String name = runtime.exportName(e);
+      if (kind == WasmerImpExpKindFunction) {
+        var f = runtime.exportToFunction(e);
         _functions[name] = WasmFunction(
-            name, f, runtime.getArgTypes(ft), runtime.getReturnType(ft));
-      } else if (kind == WasmerExternKindMemory) {
+            name, f, runtime.getArgTypes(f), runtime.getReturnType(f));
+      } else if (kind == WasmerImpExpKindMemory) {
         // WASM currently allows only one memory per module.
-        _exportedMemory = runtime.externToMemory(e);
+        _exportedMemory = runtime.exportToMemory(e);
       }
     }
   }
@@ -121,8 +107,8 @@
 
   /// Create a new memory with the given number of initial pages, and optional
   /// maximum number of pages.
-  WasmMemory._create(Pointer<WasmerStore> store, int pages, int? maxPages)
-      : _mem = WasmRuntime().newMemory(store, pages, maxPages) {
+  WasmMemory(int pages, [int? maxPages])
+      : _mem = WasmRuntime().newMemory(pages, maxPages) {
     _view = WasmRuntime().memoryView(_mem);
   }
 
diff --git a/pkg/wasm/lib/src/runtime.dart b/pkg/wasm/lib/src/runtime.dart
index 6f09208..4ddec1d 100644
--- a/pkg/wasm/lib/src/runtime.dart
+++ b/pkg/wasm/lib/src/runtime.dart
@@ -2,10 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// This file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the following command
-// "generate_ffi_boilerplate.py".
-
 import 'dart:convert';
 import 'dart:ffi';
 import 'dart:io';
@@ -18,92 +14,62 @@
   int kind;
   String moduleName;
   String name;
-  Pointer<WasmerFunctype> funcType;
-  WasmImportDescriptor(this.kind, this.moduleName, this.name, this.funcType);
+  WasmImportDescriptor(this.kind, this.moduleName, this.name);
 }
 
 class WasmExportDescriptor {
   int kind;
   String name;
-  Pointer<WasmerFunctype> funcType;
-  WasmExportDescriptor(this.kind, this.name, this.funcType);
+  WasmExportDescriptor(this.kind, this.name);
 }
 
 class WasmRuntime {
   static WasmRuntime? _inst;
 
   DynamicLibrary _lib;
-  late Pointer<WasmerEngine> _engine;
-  late WasmerByteVecDeleteFn _byte_vec_delete;
-  late WasmerByteVecNewFn _byte_vec_new;
-  late WasmerByteVecNewEmptyFn _byte_vec_new_empty;
-  late WasmerByteVecNewUninitializedFn _byte_vec_new_uninitialized;
-  late WasmerEngineDeleteFn _engine_delete;
-  late WasmerEngineNewFn _engine_new;
-  late WasmerExporttypeNameFn _exporttype_name;
-  late WasmerExporttypeTypeFn _exporttype_type;
-  late WasmerExporttypeVecDeleteFn _exporttype_vec_delete;
-  late WasmerExporttypeVecNewFn _exporttype_vec_new;
-  late WasmerExporttypeVecNewEmptyFn _exporttype_vec_new_empty;
-  late WasmerExporttypeVecNewUninitializedFn _exporttype_vec_new_uninitialized;
-  late WasmerExternAsFuncFn _extern_as_func;
-  late WasmerExternAsMemoryFn _extern_as_memory;
-  late WasmerExternDeleteFn _extern_delete;
-  late WasmerExternKindFn _extern_kind;
-  late WasmerExternVecDeleteFn _extern_vec_delete;
-  late WasmerExternVecNewFn _extern_vec_new;
-  late WasmerExternVecNewEmptyFn _extern_vec_new_empty;
-  late WasmerExternVecNewUninitializedFn _extern_vec_new_uninitialized;
-  late WasmerExterntypeAsFunctypeFn _externtype_as_functype;
-  late WasmerExterntypeDeleteFn _externtype_delete;
-  late WasmerExterntypeKindFn _externtype_kind;
-  late WasmerFuncCallFn _func_call;
-  late WasmerFuncDeleteFn _func_delete;
-  late WasmerFunctypeDeleteFn _functype_delete;
-  late WasmerFunctypeParamsFn _functype_params;
-  late WasmerFunctypeResultsFn _functype_results;
-  late WasmerImporttypeModuleFn _importtype_module;
-  late WasmerImporttypeNameFn _importtype_name;
-  late WasmerImporttypeTypeFn _importtype_type;
-  late WasmerImporttypeVecDeleteFn _importtype_vec_delete;
-  late WasmerImporttypeVecNewFn _importtype_vec_new;
-  late WasmerImporttypeVecNewEmptyFn _importtype_vec_new_empty;
-  late WasmerImporttypeVecNewUninitializedFn _importtype_vec_new_uninitialized;
-  late WasmerInstanceDeleteFn _instance_delete;
+  late WasmerCompileFn _compile;
+  late WasmerInstantiateFn _instantiate;
   late WasmerInstanceExportsFn _instance_exports;
-  late WasmerInstanceNewFn _instance_new;
-  late WasmerMemoryDataFn _memory_data;
-  late WasmerMemoryDataSizeFn _memory_data_size;
-  late WasmerMemoryDeleteFn _memory_delete;
+  late WasmerExportsLenFn _exports_len;
+  late WasmerExportsGetFn _exports_get;
+  late WasmerExportKindFn _export_kind;
+  late WasmerExportToFuncFn _export_to_func;
+  late WasmerExportFuncReturnsArityFn _export_func_returns_arity;
+  late WasmerExportFuncReturnsFn _export_func_returns;
+  late WasmerExportFuncParamsArityFn _export_func_params_arity;
+  late WasmerExportFuncParamsFn _export_func_params;
+  late WasmerExportFuncCallFn _export_func_call;
+  late WasmerExportNamePtrFn _export_name_ptr;
+  late WasmerExportDescriptorsFn _export_descriptors;
+  late WasmerExportDescriptorsDestroyFn _export_descriptors_destroy;
+  late WasmerExportDescriptorsLenFn _export_descriptors_len;
+  late WasmerExportDescriptorsGetFn _export_descriptors_get;
+  late WasmerExportDescriptorKindFn _export_descriptor_kind;
+  late WasmerExportDescriptorNamePtrFn _export_descriptor_name_ptr;
+  late WasmerImportDescriptorModuleNamePtrFn _import_descriptor_module_name_ptr;
+  late WasmerImportDescriptorNamePtrFn _import_descriptor_name_ptr;
+  late WasmerImportDescriptorsFn _import_descriptors;
+  late WasmerImportDescriptorsDestroyFn _import_descriptors_destroy;
+  late WasmerImportDescriptorsLenFn _import_descriptors_len;
+  late WasmerImportDescriptorsGetFn _import_descriptors_get;
+  late WasmerImportDescriptorKindFn _import_descriptor_kind;
+  late WasmerExportToMemoryFn _export_to_memory;
+  late WasmerMemoryNewPtrFn _memory_new_ptr;
   late WasmerMemoryGrowFn _memory_grow;
-  late WasmerMemoryNewFn _memory_new;
-  late WasmerMemorySizeFn _memory_size;
-  late WasmerMemorytypeDeleteFn _memorytype_delete;
-  late WasmerMemorytypeNewFn _memorytype_new;
-  late WasmerModuleDeleteFn _module_delete;
-  late WasmerModuleExportsFn _module_exports;
-  late WasmerModuleImportsFn _module_imports;
-  late WasmerModuleNewFn _module_new;
-  late WasmerStoreDeleteFn _store_delete;
-  late WasmerStoreNewFn _store_new;
-  late WasmerTrapDeleteFn _trap_delete;
-  late WasmerValtypeDeleteFn _valtype_delete;
-  late WasmerValtypeKindFn _valtype_kind;
-  late WasmerValtypeVecDeleteFn _valtype_vec_delete;
-  late WasmerValtypeVecNewFn _valtype_vec_new;
-  late WasmerValtypeVecNewEmptyFn _valtype_vec_new_empty;
-  late WasmerValtypeVecNewUninitializedFn _valtype_vec_new_uninitialized;
+  late WasmerMemoryLengthFn _memory_length;
+  late WasmerMemoryDataFn _memory_data;
+  late WasmerMemoryDataLengthFn _memory_data_length;
 
   factory WasmRuntime() {
-    WasmRuntime inst = _inst ?? WasmRuntime._init();
-    _inst = inst;
-    return inst;
+    if (_inst == null) {
+      _inst = WasmRuntime._init();
+    }
+    return _inst as WasmRuntime;
   }
 
   static String _getLibName() {
-    if (Platform.isMacOS) return "libwasmer.dylib";
-    if (Platform.isLinux) return "libwasmer.so";
-    // TODO(dartbug.com/37882): Support more platforms.
+    if (Platform.isMacOS) return "libwasmer_wrapper.dylib";
+    if (Platform.isLinux) return "libwasmer_wrapper.so";
     throw Exception("Wasm not currently supported on this platform");
   }
 
@@ -138,322 +104,296 @@
 
   WasmRuntime._init()
       : _lib = DynamicLibrary.open(path.join(_getLibDir(), _getLibName())) {
-    _byte_vec_delete =
-        _lib.lookupFunction<NativeWasmerByteVecDeleteFn, WasmerByteVecDeleteFn>(
-            'wasm_byte_vec_delete');
-    _byte_vec_new =
-        _lib.lookupFunction<NativeWasmerByteVecNewFn, WasmerByteVecNewFn>(
-            'wasm_byte_vec_new');
-    _byte_vec_new_empty = _lib.lookupFunction<NativeWasmerByteVecNewEmptyFn,
-        WasmerByteVecNewEmptyFn>('wasm_byte_vec_new_empty');
-    _byte_vec_new_uninitialized = _lib.lookupFunction<
-        NativeWasmerByteVecNewUninitializedFn,
-        WasmerByteVecNewUninitializedFn>('wasm_byte_vec_new_uninitialized');
-    _engine_delete =
-        _lib.lookupFunction<NativeWasmerEngineDeleteFn, WasmerEngineDeleteFn>(
-            'wasm_engine_delete');
-    _engine_new =
-        _lib.lookupFunction<NativeWasmerEngineNewFn, WasmerEngineNewFn>(
-            'wasm_engine_new');
-    _exporttype_name = _lib.lookupFunction<NativeWasmerExporttypeNameFn,
-        WasmerExporttypeNameFn>('wasm_exporttype_name');
-    _exporttype_type = _lib.lookupFunction<NativeWasmerExporttypeTypeFn,
-        WasmerExporttypeTypeFn>('wasm_exporttype_type');
-    _exporttype_vec_delete = _lib.lookupFunction<
-        NativeWasmerExporttypeVecDeleteFn,
-        WasmerExporttypeVecDeleteFn>('wasm_exporttype_vec_delete');
-    _exporttype_vec_new = _lib.lookupFunction<NativeWasmerExporttypeVecNewFn,
-        WasmerExporttypeVecNewFn>('wasm_exporttype_vec_new');
-    _exporttype_vec_new_empty = _lib.lookupFunction<
-        NativeWasmerExporttypeVecNewEmptyFn,
-        WasmerExporttypeVecNewEmptyFn>('wasm_exporttype_vec_new_empty');
-    _exporttype_vec_new_uninitialized = _lib.lookupFunction<
-            NativeWasmerExporttypeVecNewUninitializedFn,
-            WasmerExporttypeVecNewUninitializedFn>(
-        'wasm_exporttype_vec_new_uninitialized');
-    _extern_as_func =
-        _lib.lookupFunction<NativeWasmerExternAsFuncFn, WasmerExternAsFuncFn>(
-            'wasm_extern_as_func');
-    _extern_as_memory = _lib.lookupFunction<NativeWasmerExternAsMemoryFn,
-        WasmerExternAsMemoryFn>('wasm_extern_as_memory');
-    _extern_delete =
-        _lib.lookupFunction<NativeWasmerExternDeleteFn, WasmerExternDeleteFn>(
-            'wasm_extern_delete');
-    _extern_kind =
-        _lib.lookupFunction<NativeWasmerExternKindFn, WasmerExternKindFn>(
-            'wasm_extern_kind');
-    _extern_vec_delete = _lib.lookupFunction<NativeWasmerExternVecDeleteFn,
-        WasmerExternVecDeleteFn>('wasm_extern_vec_delete');
-    _extern_vec_new =
-        _lib.lookupFunction<NativeWasmerExternVecNewFn, WasmerExternVecNewFn>(
-            'wasm_extern_vec_new');
-    _extern_vec_new_empty = _lib.lookupFunction<NativeWasmerExternVecNewEmptyFn,
-        WasmerExternVecNewEmptyFn>('wasm_extern_vec_new_empty');
-    _extern_vec_new_uninitialized = _lib.lookupFunction<
-        NativeWasmerExternVecNewUninitializedFn,
-        WasmerExternVecNewUninitializedFn>('wasm_extern_vec_new_uninitialized');
-    _externtype_as_functype = _lib.lookupFunction<
-        NativeWasmerExterntypeAsFunctypeFn,
-        WasmerExterntypeAsFunctypeFn>('wasm_externtype_as_functype');
-    _externtype_delete = _lib.lookupFunction<NativeWasmerExterntypeDeleteFn,
-        WasmerExterntypeDeleteFn>('wasm_externtype_delete');
-    _externtype_kind = _lib.lookupFunction<NativeWasmerExterntypeKindFn,
-        WasmerExterntypeKindFn>('wasm_externtype_kind');
-    _func_call = _lib.lookupFunction<NativeWasmerFuncCallFn, WasmerFuncCallFn>(
-        'wasm_func_call');
-    _func_delete =
-        _lib.lookupFunction<NativeWasmerFuncDeleteFn, WasmerFuncDeleteFn>(
-            'wasm_func_delete');
-    _functype_delete = _lib.lookupFunction<NativeWasmerFunctypeDeleteFn,
-        WasmerFunctypeDeleteFn>('wasm_functype_delete');
-    _functype_params = _lib.lookupFunction<NativeWasmerFunctypeParamsFn,
-        WasmerFunctypeParamsFn>('wasm_functype_params');
-    _functype_results = _lib.lookupFunction<NativeWasmerFunctypeResultsFn,
-        WasmerFunctypeResultsFn>('wasm_functype_results');
-    _importtype_module = _lib.lookupFunction<NativeWasmerImporttypeModuleFn,
-        WasmerImporttypeModuleFn>('wasm_importtype_module');
-    _importtype_name = _lib.lookupFunction<NativeWasmerImporttypeNameFn,
-        WasmerImporttypeNameFn>('wasm_importtype_name');
-    _importtype_type = _lib.lookupFunction<NativeWasmerImporttypeTypeFn,
-        WasmerImporttypeTypeFn>('wasm_importtype_type');
-    _importtype_vec_delete = _lib.lookupFunction<
-        NativeWasmerImporttypeVecDeleteFn,
-        WasmerImporttypeVecDeleteFn>('wasm_importtype_vec_delete');
-    _importtype_vec_new = _lib.lookupFunction<NativeWasmerImporttypeVecNewFn,
-        WasmerImporttypeVecNewFn>('wasm_importtype_vec_new');
-    _importtype_vec_new_empty = _lib.lookupFunction<
-        NativeWasmerImporttypeVecNewEmptyFn,
-        WasmerImporttypeVecNewEmptyFn>('wasm_importtype_vec_new_empty');
-    _importtype_vec_new_uninitialized = _lib.lookupFunction<
-            NativeWasmerImporttypeVecNewUninitializedFn,
-            WasmerImporttypeVecNewUninitializedFn>(
-        'wasm_importtype_vec_new_uninitialized');
-    _instance_delete = _lib.lookupFunction<NativeWasmerInstanceDeleteFn,
-        WasmerInstanceDeleteFn>('wasm_instance_delete');
+    _compile = _lib.lookupFunction<NativeWasmerCompileFn, WasmerCompileFn>(
+        'wasmer_compile');
+    _instantiate =
+        _lib.lookupFunction<NativeWasmerInstantiateFn, WasmerInstantiateFn>(
+            'wasmer_module_instantiate');
     _instance_exports = _lib.lookupFunction<NativeWasmerInstanceExportsFn,
-        WasmerInstanceExportsFn>('wasm_instance_exports');
-    _instance_new =
-        _lib.lookupFunction<NativeWasmerInstanceNewFn, WasmerInstanceNewFn>(
-            'wasm_instance_new');
-    _memory_data =
-        _lib.lookupFunction<NativeWasmerMemoryDataFn, WasmerMemoryDataFn>(
-            'wasm_memory_data');
-    _memory_data_size = _lib.lookupFunction<NativeWasmerMemoryDataSizeFn,
-        WasmerMemoryDataSizeFn>('wasm_memory_data_size');
-    _memory_delete =
-        _lib.lookupFunction<NativeWasmerMemoryDeleteFn, WasmerMemoryDeleteFn>(
-            'wasm_memory_delete');
+        WasmerInstanceExportsFn>('wasmer_instance_exports');
+    _exports_len =
+        _lib.lookupFunction<NativeWasmerExportsLenFn, WasmerExportsLenFn>(
+            'wasmer_exports_len');
+    _exports_get =
+        _lib.lookupFunction<NativeWasmerExportsGetFn, WasmerExportsGetFn>(
+            'wasmer_exports_get');
+    _export_kind =
+        _lib.lookupFunction<NativeWasmerExportKindFn, WasmerExportKindFn>(
+            'wasmer_export_kind');
+    _export_to_func =
+        _lib.lookupFunction<NativeWasmerExportToFuncFn, WasmerExportToFuncFn>(
+            'wasmer_export_to_func');
+    _export_func_returns_arity = _lib.lookupFunction<
+        NativeWasmerExportFuncReturnsArityFn,
+        WasmerExportFuncReturnsArityFn>('wasmer_export_func_returns_arity');
+    _export_func_returns = _lib.lookupFunction<NativeWasmerExportFuncReturnsFn,
+        WasmerExportFuncReturnsFn>('wasmer_export_func_returns');
+    _export_func_params_arity = _lib.lookupFunction<
+        NativeWasmerExportFuncParamsArityFn,
+        WasmerExportFuncParamsArityFn>('wasmer_export_func_params_arity');
+    _export_func_params = _lib.lookupFunction<NativeWasmerExportFuncParamsFn,
+        WasmerExportFuncParamsFn>('wasmer_export_func_params');
+    _export_func_call = _lib.lookupFunction<NativeWasmerExportFuncCallFn,
+        WasmerExportFuncCallFn>('wasmer_export_func_call');
+    _export_descriptors = _lib.lookupFunction<NativeWasmerExportDescriptorsFn,
+        WasmerExportDescriptorsFn>('wasmer_export_descriptors');
+    _export_descriptors_destroy = _lib.lookupFunction<
+        NativeWasmerExportDescriptorsDestroyFn,
+        WasmerExportDescriptorsDestroyFn>('wasmer_export_descriptors_destroy');
+    _export_descriptors_len = _lib.lookupFunction<
+        NativeWasmerExportDescriptorsLenFn,
+        WasmerExportDescriptorsLenFn>('wasmer_export_descriptors_len');
+    _export_descriptors_get = _lib.lookupFunction<
+        NativeWasmerExportDescriptorsGetFn,
+        WasmerExportDescriptorsGetFn>('wasmer_export_descriptors_get');
+    _export_descriptor_kind = _lib.lookupFunction<
+        NativeWasmerExportDescriptorKindFn,
+        WasmerExportDescriptorKindFn>('wasmer_export_descriptor_kind');
+    _export_name_ptr =
+        _lib.lookupFunction<NativeWasmerExportNamePtrFn, WasmerExportNamePtrFn>(
+            'wasmer_export_name_ptr');
+    _export_descriptor_name_ptr = _lib.lookupFunction<
+        NativeWasmerExportDescriptorNamePtrFn,
+        WasmerExportDescriptorNamePtrFn>('wasmer_export_descriptor_name_ptr');
+    _import_descriptors = _lib.lookupFunction<NativeWasmerImportDescriptorsFn,
+        WasmerImportDescriptorsFn>('wasmer_import_descriptors');
+    _import_descriptors_destroy = _lib.lookupFunction<
+        NativeWasmerImportDescriptorsDestroyFn,
+        WasmerImportDescriptorsDestroyFn>('wasmer_import_descriptors_destroy');
+    _import_descriptors_len = _lib.lookupFunction<
+        NativeWasmerImportDescriptorsLenFn,
+        WasmerImportDescriptorsLenFn>('wasmer_import_descriptors_len');
+    _import_descriptors_get = _lib.lookupFunction<
+        NativeWasmerImportDescriptorsGetFn,
+        WasmerImportDescriptorsGetFn>('wasmer_import_descriptors_get');
+    _import_descriptor_kind = _lib.lookupFunction<
+        NativeWasmerImportDescriptorKindFn,
+        WasmerImportDescriptorKindFn>('wasmer_import_descriptor_kind');
+    _import_descriptor_module_name_ptr = _lib.lookupFunction<
+            NativeWasmerImportDescriptorModuleNamePtrFn,
+            WasmerImportDescriptorModuleNamePtrFn>(
+        'wasmer_import_descriptor_module_name_ptr');
+    _import_descriptor_name_ptr = _lib.lookupFunction<
+        NativeWasmerImportDescriptorNamePtrFn,
+        WasmerImportDescriptorNamePtrFn>('wasmer_import_descriptor_name_ptr');
+    _export_to_memory = _lib.lookupFunction<NativeWasmerExportToMemoryFn,
+        WasmerExportToMemoryFn>('wasmer_export_to_memory');
+    _memory_new_ptr =
+        _lib.lookupFunction<NativeWasmerMemoryNewPtrFn, WasmerMemoryNewPtrFn>(
+            'wasmer_memory_new_ptr');
     _memory_grow =
         _lib.lookupFunction<NativeWasmerMemoryGrowFn, WasmerMemoryGrowFn>(
-            'wasm_memory_grow');
-    _memory_new =
-        _lib.lookupFunction<NativeWasmerMemoryNewFn, WasmerMemoryNewFn>(
-            'wasm_memory_new');
-    _memory_size =
-        _lib.lookupFunction<NativeWasmerMemorySizeFn, WasmerMemorySizeFn>(
-            'wasm_memory_size');
-    _memorytype_delete = _lib.lookupFunction<NativeWasmerMemorytypeDeleteFn,
-        WasmerMemorytypeDeleteFn>('wasm_memorytype_delete');
-    _memorytype_new =
-        _lib.lookupFunction<NativeWasmerMemorytypeNewFn, WasmerMemorytypeNewFn>(
-            'wasm_memorytype_new');
-    _module_delete =
-        _lib.lookupFunction<NativeWasmerModuleDeleteFn, WasmerModuleDeleteFn>(
-            'wasm_module_delete');
-    _module_exports =
-        _lib.lookupFunction<NativeWasmerModuleExportsFn, WasmerModuleExportsFn>(
-            'wasm_module_exports');
-    _module_imports =
-        _lib.lookupFunction<NativeWasmerModuleImportsFn, WasmerModuleImportsFn>(
-            'wasm_module_imports');
-    _module_new =
-        _lib.lookupFunction<NativeWasmerModuleNewFn, WasmerModuleNewFn>(
-            'wasm_module_new');
-    _store_delete =
-        _lib.lookupFunction<NativeWasmerStoreDeleteFn, WasmerStoreDeleteFn>(
-            'wasm_store_delete');
-    _store_new = _lib.lookupFunction<NativeWasmerStoreNewFn, WasmerStoreNewFn>(
-        'wasm_store_new');
-    _trap_delete =
-        _lib.lookupFunction<NativeWasmerTrapDeleteFn, WasmerTrapDeleteFn>(
-            'wasm_trap_delete');
-    _valtype_delete =
-        _lib.lookupFunction<NativeWasmerValtypeDeleteFn, WasmerValtypeDeleteFn>(
-            'wasm_valtype_delete');
-    _valtype_kind =
-        _lib.lookupFunction<NativeWasmerValtypeKindFn, WasmerValtypeKindFn>(
-            'wasm_valtype_kind');
-    _valtype_vec_delete = _lib.lookupFunction<NativeWasmerValtypeVecDeleteFn,
-        WasmerValtypeVecDeleteFn>('wasm_valtype_vec_delete');
-    _valtype_vec_new =
-        _lib.lookupFunction<NativeWasmerValtypeVecNewFn, WasmerValtypeVecNewFn>(
-            'wasm_valtype_vec_new');
-    _valtype_vec_new_empty = _lib.lookupFunction<
-        NativeWasmerValtypeVecNewEmptyFn,
-        WasmerValtypeVecNewEmptyFn>('wasm_valtype_vec_new_empty');
-    _valtype_vec_new_uninitialized = _lib.lookupFunction<
-            NativeWasmerValtypeVecNewUninitializedFn,
-            WasmerValtypeVecNewUninitializedFn>(
-        'wasm_valtype_vec_new_uninitialized');
-
-    _engine = _engine_new();
+            'wasmer_memory_grow');
+    _memory_length =
+        _lib.lookupFunction<NativeWasmerMemoryLengthFn, WasmerMemoryLengthFn>(
+            'wasmer_memory_length');
+    _memory_data =
+        _lib.lookupFunction<NativeWasmerMemoryDataFn, WasmerMemoryDataFn>(
+            'wasmer_memory_data');
+    _memory_data_length = _lib.lookupFunction<NativeWasmerMemoryDataLengthFn,
+        WasmerMemoryDataLengthFn>('wasmer_memory_data_length');
   }
 
-  Pointer<WasmerStore> newStore() {
-    return _store_new(_engine);
-  }
-
-  Pointer<WasmerModule> compile(Pointer<WasmerStore> store, Uint8List data) {
+  Pointer<WasmerModule> compile(Uint8List data) {
     var dataPtr = allocate<Uint8>(count: data.length);
     for (int i = 0; i < data.length; ++i) {
       dataPtr[i] = data[i];
     }
-    var dataVec = allocate<WasmerByteVec>();
-    dataVec.ref.data = dataPtr;
-    dataVec.ref.length = data.length;
 
-    var modulePtr = _module_new(store, dataVec);
+    var modulePtrPtr = allocate<Pointer<WasmerModule>>();
+    int result = _compile(modulePtrPtr, dataPtr, data.length);
+    Pointer<WasmerModule> modulePtr = modulePtrPtr.value;
 
+    free(modulePtrPtr);
     free(dataPtr);
-    free(dataVec);
 
-    if (modulePtr == nullptr) {
+    if (result != WasmerResultOk) {
       throw Exception("Wasm module compile failed");
     }
 
     return modulePtr;
   }
 
+  String _callStringWrapperFunction(Function fn, dynamic arg) {
+    var strPtr = allocate<WasmerByteArray>();
+    fn(arg, strPtr);
+    var str = strPtr.ref.string;
+    free(strPtr);
+    return str;
+  }
+
   List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
-    var exportsVec = allocate<WasmerExporttypeVec>();
-    _module_exports(module, exportsVec);
+    var exportsPtrPtr = allocate<Pointer<WasmerExportDescriptors>>();
+    _export_descriptors(module, exportsPtrPtr);
+    Pointer<WasmerExportDescriptors> exportsPtr = exportsPtrPtr.value;
+    free(exportsPtrPtr);
+    var n = _export_descriptors_len(exportsPtr);
     var exps = <WasmExportDescriptor>[];
-    for (var i = 0; i < exportsVec.ref.length; ++i) {
-      var exp = exportsVec.ref.data[i];
-      var extern = _exporttype_type(exp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      exps.add(WasmExportDescriptor(
-          kind, _exporttype_name(exp).ref.toString(), fnType));
+    for (var i = 0; i < n; ++i) {
+      var exp = _export_descriptors_get(exportsPtr, i);
+      exps.add(WasmExportDescriptor(_export_descriptor_kind(exp),
+          _callStringWrapperFunction(_export_descriptor_name_ptr, exp)));
     }
-    free(exportsVec);
+    _export_descriptors_destroy(exportsPtr);
     return exps;
   }
 
   List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
-    var importsVec = allocate<WasmerImporttypeVec>();
-    _module_imports(module, importsVec);
+    var importsPtrPtr = allocate<Pointer<WasmerImportDescriptors>>();
+    _import_descriptors(module, importsPtrPtr);
+    Pointer<WasmerImportDescriptors> importsPtr = importsPtrPtr.value;
+    free(importsPtrPtr);
+
+    var n = _import_descriptors_len(importsPtr);
     var imps = <WasmImportDescriptor>[];
-    for (var i = 0; i < importsVec.ref.length; ++i) {
-      var imp = importsVec.ref.data[i];
-      var extern = _importtype_type(imp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
+    for (var i = 0; i < n; ++i) {
+      var imp = _import_descriptors_get(importsPtr, i);
       imps.add(WasmImportDescriptor(
-          kind,
-          _importtype_module(imp).ref.toString(),
-          _importtype_name(imp).ref.toString(),
-          fnType));
+          _import_descriptor_kind(imp),
+          _callStringWrapperFunction(_import_descriptor_module_name_ptr, imp),
+          _callStringWrapperFunction(_import_descriptor_name_ptr, imp)));
     }
-    free(importsVec);
+    _import_descriptors_destroy(importsPtr);
     return imps;
   }
 
-  Pointer<WasmerInstance> instantiate(
-      Pointer<WasmerStore> store,
-      Pointer<WasmerModule> module,
-      Pointer<Pointer<WasmerExtern>> imports,
-      int numImports) {
-    var importsVec = allocate<WasmerImporttypeVec>();
-    _module_imports(module, importsVec);
-    if (importsVec.ref.length != numImports) {
-      throw Exception(
-          "Wrong number of imports. Expected ${importsVec.ref.length} but " +
-              "found $numImports.");
-    }
-    free(importsVec);
+  Pointer<WasmerInstance> instantiate(Pointer<WasmerModule> module,
+      Pointer<WasmerImport> imports, int numImports) {
+    var instancePtrPtr = allocate<Pointer<WasmerInstance>>();
+    int result = _instantiate(module, instancePtrPtr, imports, numImports);
+    Pointer<WasmerInstance> instancePtr = instancePtrPtr.value;
+    free(instancePtrPtr);
 
-    var instancePtr = _instance_new(store, module, imports, nullptr);
-    if (instancePtr == nullptr) {
+    if (result != WasmerResultOk) {
       throw Exception("Wasm module instantiation failed");
     }
 
     return instancePtr;
   }
 
-  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
-    var exports = allocate<WasmerExternVec>();
-    _instance_exports(instancePtr, exports);
-    return exports;
-  }
+  List<Pointer<WasmerExport>> exports(Pointer<WasmerInstance> instancePtr) {
+    var exportsPtrPtr = allocate<Pointer<WasmerExports>>();
+    _instance_exports(instancePtr, exportsPtrPtr);
+    Pointer<WasmerExports> exportsPtr = exportsPtrPtr.value;
+    free(exportsPtrPtr);
 
-  int externKind(Pointer<WasmerExtern> extern) {
-    return _extern_kind(extern);
-  }
-
-  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) {
-    return _extern_as_func(extern);
-  }
-
-  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
-    var types = <int>[];
-    var args = _functype_params(funcType);
-    for (var i = 0; i < args.ref.length; ++i) {
-      types.add(_valtype_kind(args.ref.data[i]));
+    var n = _exports_len(exportsPtr);
+    var exps = <Pointer<WasmerExport>>[];
+    for (var i = 0; i < n; ++i) {
+      exps.add(_exports_get(exportsPtr, i));
     }
+    return exps;
+  }
+
+  int exportKind(Pointer<WasmerExport> export) {
+    return _export_kind(export);
+  }
+
+  String exportName(Pointer<WasmerExport> export) {
+    return _callStringWrapperFunction(_export_name_ptr, export);
+  }
+
+  Pointer<WasmerExportFunc> exportToFunction(Pointer<WasmerExport> export) {
+    return _export_to_func(export);
+  }
+
+  List<int> getArgTypes(Pointer<WasmerExportFunc> func) {
+    var types = <int>[];
+    var nPtr = allocate<Uint32>();
+    var result = _export_func_params_arity(func, nPtr);
+    if (result != WasmerResultOk) {
+      free(nPtr);
+      throw Exception("Failed to get number of WASM function args");
+    }
+    var n = nPtr.value;
+    free(nPtr);
+    var argsPtr = allocate<Uint32>(count: n);
+    result = _export_func_params(func, argsPtr, n);
+    if (result != WasmerResultOk) {
+      free(argsPtr);
+      throw Exception("Failed to get WASM function args");
+    }
+    for (var i = 0; i < n; ++i) {
+      types.add(argsPtr[i]);
+    }
+    free(argsPtr);
     return types;
   }
 
-  int getReturnType(Pointer<WasmerFunctype> funcType) {
-    var rets = _functype_results(funcType);
-    if (rets.ref.length == 0) {
-      return WasmerValKindVoid;
-    } else if (rets.ref.length > 1) {
+  int getReturnType(Pointer<WasmerExportFunc> func) {
+    var nPtr = allocate<Uint32>();
+    var result = _export_func_returns_arity(func, nPtr);
+    if (result != WasmerResultOk) {
+      free(nPtr);
+      throw Exception("Failed to get number of WASM function returns");
+    }
+    var n = nPtr.value;
+    free(nPtr);
+    if (n == 0) {
+      return WasmerValueTagVoid;
+    } else if (n > 1) {
       throw Exception("Multiple return values are not supported");
     }
-    return _valtype_kind(rets.ref.data[0]);
+    var returnsPtr = allocate<Uint32>();
+    result = _export_func_returns(func, returnsPtr, 1);
+    if (result != WasmerResultOk) {
+      free(returnsPtr);
+      throw Exception("Failed to get WASM function args");
+    }
+    var type = returnsPtr.value;
+    free(returnsPtr);
+    return type;
   }
 
-  void call(Pointer<WasmerFunc> func, Pointer<WasmerVal> args,
-      Pointer<WasmerVal> results) {
-    _func_call(func, args, results);
+  void call(Pointer<WasmerExportFunc> func, Pointer<WasmerValue> args,
+      int numArgs, Pointer<WasmerValue> results, int numResults) {
+    var result = _export_func_call(func, args, numArgs, results, numArgs);
+    if (result != WasmerResultOk) {
+      throw Exception("Failed to call WASM function");
+    }
   }
 
-  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) {
-    return _extern_as_memory(extern);
+  Pointer<WasmerMemory> exportToMemory(Pointer<WasmerExport> export) {
+    var memPtrPtr = allocate<Pointer<WasmerMemory>>();
+    var result = _export_to_memory(export, memPtrPtr);
+    if (result != WasmerResultOk) {
+      free(memPtrPtr);
+      throw Exception("Failed to get exported memory");
+    }
+    Pointer<WasmerMemory> memPtr = memPtrPtr.value;
+    free(memPtrPtr);
+    return memPtr;
   }
 
-  Pointer<WasmerMemory> newMemory(
-      Pointer<WasmerStore> store, int pages, int? maxPages) {
+  Pointer<WasmerMemory> newMemory(int pages, int? maxPages) {
+    var memPtrPtr = allocate<Pointer<WasmerMemory>>();
     var limPtr = allocate<WasmerLimits>();
     limPtr.ref.min = pages;
-    limPtr.ref.max = maxPages ?? wasm_limits_max_default;
-    var memType = _memorytype_new(limPtr);
+    limPtr.ref.has_max = maxPages != null ? 1 : 0;
+    limPtr.ref.max = maxPages ?? 0;
+    var result = _memory_new_ptr(memPtrPtr, limPtr);
     free(limPtr);
-    Pointer<WasmerMemory> memPtr = _memory_new(store, memType);
-
-    if (memPtr == nullptr) {
+    if (result != WasmerResultOk) {
+      free(memPtrPtr);
       throw Exception("Failed to create memory");
     }
+    Pointer<WasmerMemory> memPtr = memPtrPtr.value;
+    free(memPtrPtr);
     return memPtr;
   }
 
   void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
     var result = _memory_grow(memory, deltaPages);
-    if (result == 0) {
+    if (result != WasmerResultOk) {
       throw Exception("Failed to grow memory");
     }
   }
 
   int memoryLength(Pointer<WasmerMemory> memory) {
-    return _memory_size(memory);
+    return _memory_length(memory);
   }
 
   Uint8List memoryView(Pointer<WasmerMemory> memory) {
-    return _memory_data(memory).asTypedList(_memory_data_size(memory));
+    return _memory_data(memory).asTypedList(_memory_data_length(memory));
   }
 }
diff --git a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py b/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
deleted file mode 100755
index cf9621c..0000000
--- a/pkg/wasm/lib/src/tools/generate_ffi_boilerplate.py
+++ /dev/null
@@ -1,340 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This is an ad-hoc script that generates FFI boilderplate for the Wasmer API.
-# The relevant functions from wasm.h have been copied below, and are parsed to
-# figure out the FFI boilerplate. The results are inserted into
-# wasmer_api_template.dart and runtime_template.dart to generate wasmer_api.dart
-# and runtime.dart.
-
-# Usage:
-# generate_ffi_boilerplate.py && dartfmt -w ../runtime.dart ../wasmer_api.dart
-
-import os
-import re
-
-predefTypes = {}
-opaqueTypes = set()
-vecTypes = {}
-fns = []
-unusedFns = set()
-
-
-def camel(t):
-    return ''.join([s[0].upper() + s[1:] for s in t.split('_')])
-
-
-def ptrWrap(t, n):
-    for i in range(n):
-        t = 'Pointer<%s>' % t
-    return 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
-
-
-def dartArgType(a, i):
-    n, t = a
-    j = i if n == 0 else 0
-    return ptrWrap(getDartType(t, j), n)
-
-
-def dartFnType(r, a, i):
-    return '%s Function(%s)' % (dartArgType(r, i), ', '.join(
-        [dartArgType(t, i) for t in a]))
-
-
-def dartFnTypeName(n):
-    assert (n.startswith('wasm_'))
-    return camel(n[5:])
-
-
-def dartFnMembName(n):
-    assert (n.startswith('wasm_'))
-    return n[4:]
-
-
-def nativeTypeToFfi(n):
-    return getDartType(n, 0)
-
-
-def nativeTypeToDart(n):
-    return getDartType(n, 1)
-
-
-def getFns():
-    for name, retType, args in sorted(fns):
-        if name not in unusedFns:
-            yield name, retType, args
-
-
-opaqueTypeTemplate = '''// wasm_%s_t
-class Wasmer%s extends Struct {}'''
-
-vecTypeTemplate = '''// wasm_%s_vec_t
-class Wasmer%sVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<%s> data;
-
-  %s
-}'''
-
-byteVecToStringTemplate = '''
-  Uint8List get list => data.asTypedList(length);
-  String toString() => utf8.decode(list);
-'''
-
-fnApiTemplate = '''
-// %s
-typedef NativeWasmer%sFn = %s;
-typedef Wasmer%sFn = %s;'''
-
-
-def getWasmerApi():
-    return ('\n\n'.join([
-        opaqueTypeTemplate % (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 ''))
-        for t, ptr in sorted(vecTypes.items())
-    ]) + '\n' + '\n'.join([
-        fnApiTemplate %
-        (name, dartFnTypeName(name), dartFnType(retType, args, 0),
-         dartFnTypeName(name), dartFnType(retType, args, 1))
-        for name, retType, args in getFns()
-    ]))
-
-
-def getRuntimeMemb():
-    return '\n'.join([
-        "  late Wasmer%sFn %s;" % (dartFnTypeName(name), dartFnMembName(name))
-        for name, _, _ in getFns()
-    ])
-
-
-def getRuntimeLoad():
-    return '\n'.join([
-        "    %s = _lib.lookupFunction<NativeWasmer%sFn, Wasmer%sFn>('%s');" %
-        (dartFnMembName(name), dartFnTypeName(name), dartFnTypeName(name), name)
-        for name, _, _ in getFns()
-    ])
-
-
-def predefinedType(nativeType, ffiType, dartType):
-    predefTypes[nativeType] = (ffiType, dartType)
-
-
-def match(r, s):
-    return r.fullmatch(s).groups()
-
-
-reReplace = [(re.compile('\\b%s\\b' % k), v) for k, v in [
-    ('const', ''),
-    ('own', ''),
-    ('WASM_API_EXTERN', ''),
-    ('wasm_name_t', 'wasm_byte_vec_t'),
-    ('wasm_memory_pages_t', 'uint32_t'),
-    ('wasm_externkind_t', 'uint8_t'),
-    ('wasm_valkind_t', 'uint8_t'),
-]]
-reWord = re.compile(r'\b\w+\b')
-
-
-def parseType(s):
-    for r, t in reReplace:
-        s = r.sub(t, s)
-    s = s.strip()
-    numWords = len(reWord.findall(s))
-    assert (numWords == 1 or numWords == 2)
-    if numWords == 2:
-        i = 0
-
-        def lastWordRepl(m):
-            nonlocal i
-            i += 1
-            return '' if i == numWords else m.group(0)
-
-        s = reWord.sub(lastWordRepl, s)
-    numPtr = 0
-    while True:
-        s = s.strip()
-        if s.endswith('*'):
-            s = s[:-1]
-        elif s.endswith('[]'):
-            s = s[:-2]
-        else:
-            break
-        numPtr += 1
-    return (numPtr, s)
-
-
-reFnSig = re.compile(r'(.*) ([^ ]*)\((.*)\);?')
-
-
-def addFn(sig):
-    ret, name, argpack = match(reFnSig, sig)
-    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:
-            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))
-
-
-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))
-
-
-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))
-
-
-predefinedType('void', 'Void', 'void')
-predefinedType('bool', 'Uint8', 'int')
-predefinedType('byte_t', 'Uint8', 'int')
-predefinedType('wasm_byte_t', 'Uint8', 'int')
-predefinedType('uint8_t', 'Uint8', 'int')
-predefinedType('uint16_t', 'Uint16', 'int')
-predefinedType('uint32_t', 'Uint32', 'int')
-predefinedType('uint64_t', 'Uint64', 'int')
-predefinedType('size_t', 'Uint64', 'int')
-predefinedType('int8_t', 'Int8', 'int')
-predefinedType('int16_t', 'Int16', 'int')
-predefinedType('int32_t', 'Int32', 'int')
-predefinedType('int64_t', 'Int64', 'int')
-predefinedType('float32_t', 'Float32', 'double')
-predefinedType('float64_t', 'Float64', 'double')
-predefinedType('wasm_limits_t', 'WasmerLimits', 'WasmerLimits')
-predefinedType('wasm_val_t', 'WasmerVal', 'WasmerVal')
-
-declareOwn('engine')
-declareOwn('store')
-declareVec('byte', False)
-declareVec('val', False)
-declareType('importtype')
-declareType('exporttype')
-declareType('valtype')
-declareType('extern', False)
-
-# These are actually DECLARE_TYPE, but we don't need the vec or copy stuff.
-declareOwn('memorytype')
-declareOwn('externtype')
-declareOwn('functype')
-
-# These are actually DECLARE_SHARABLE_REF, but we don't need the ref stuff.
-declareOwn('module')
-
-# These are actually DECLARE_REF, but we don't need the ref stuff.
-declareOwn('memory')
-declareOwn('trap')
-declareOwn('instance')
-declareOwn('func')
-
-rawFns = '''
-WASM_API_EXTERN own wasm_engine_t* wasm_engine_new();
-WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*);
-WASM_API_EXTERN own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*);
-WASM_API_EXTERN own wasm_module_t* wasm_module_new(wasm_store_t*, const wasm_byte_vec_t* binary);
-WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out);
-WASM_API_EXTERN const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*);
-WASM_API_EXTERN const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*);
-WASM_API_EXTERN const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*);
-WASM_API_EXTERN wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*);
-WASM_API_EXTERN void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_vec_t* out);
-WASM_API_EXTERN const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*);
-WASM_API_EXTERN const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*);
-WASM_API_EXTERN wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*);
-WASM_API_EXTERN own wasm_instance_t* wasm_instance_new(wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[], own wasm_trap_t**);
-WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
-WASM_API_EXTERN own wasm_memory_t* wasm_memory_new(wasm_store_t*, const wasm_memorytype_t*);
-WASM_API_EXTERN byte_t* wasm_memory_data(wasm_memory_t*);
-WASM_API_EXTERN size_t wasm_memory_data_size(const wasm_memory_t*);
-WASM_API_EXTERN wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*);
-WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
-WASM_API_EXTERN wasm_externkind_t wasm_extern_kind(const wasm_extern_t*);
-WASM_API_EXTERN wasm_func_t* wasm_extern_as_func(wasm_extern_t*);
-WASM_API_EXTERN wasm_memory_t* wasm_extern_as_memory(wasm_extern_t*);
-WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*);
-WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*);
-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*);
-'''
-for f in rawFns.split('\n'):
-    if len(f.strip()) > 0:
-        addFn(f)
-
-unusedFns = {
-    'wasm_byte_vec_copy',
-    'wasm_exporttype_delete',
-    'wasm_exporttype_copy',
-    'wasm_exporttype_vec_copy',
-    'wasm_extern_vec_copy',
-    'wasm_importtype_delete',
-    'wasm_importtype_copy',
-    'wasm_importtype_vec_copy',
-    'wasm_val_vec_copy',
-    'wasm_val_vec_delete',
-    'wasm_val_vec_new',
-    'wasm_val_vec_new_empty',
-    'wasm_val_vec_new_uninitialized',
-    'wasm_valtype_copy',
-    'wasm_valtype_vec_copy',
-}
-
-genDoc = '''// This file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the following command
-// "generate_ffi_boilerplate.py".'''
-
-thisDir = os.path.dirname(os.path.abspath(__file__))
-
-
-def readFile(filename):
-    with open(os.path.abspath(os.path.join(thisDir, filename)), 'r') as f:
-        return f.read()
-
-
-def writeFile(filename, content):
-    with open(os.path.abspath(os.path.join(thisDir, '..', filename)), 'w') as f:
-        f.write(content)
-
-
-wasmerApiText = readFile('wasmer_api_template.dart')
-wasmerApiText = wasmerApiText.replace('/* <WASMER_API> */', getWasmerApi())
-wasmerApiText = wasmerApiText.replace('/* <GEN_DOC> */', genDoc)
-writeFile('wasmer_api.dart', wasmerApiText)
-
-runtimeText = readFile('runtime_template.dart')
-runtimeText = runtimeText.replace('/* <RUNTIME_MEMB> */', getRuntimeMemb())
-runtimeText = runtimeText.replace('/* <RUNTIME_LOAD> */', getRuntimeLoad())
-runtimeText = runtimeText.replace('/* <GEN_DOC> */', genDoc)
-writeFile('runtime.dart', runtimeText)
diff --git a/pkg/wasm/lib/src/tools/runtime_template.dart b/pkg/wasm/lib/src/tools/runtime_template.dart
deleted file mode 100644
index d403882..0000000
--- a/pkg/wasm/lib/src/tools/runtime_template.dart
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/* <GEN_DOC> */
-
-import 'dart:convert';
-import 'dart:ffi';
-import 'dart:io';
-import 'dart:typed_data';
-import 'package:ffi/ffi.dart';
-import 'package:path/path.dart' as path;
-import 'wasmer_api.dart';
-
-class WasmImportDescriptor {
-  int kind;
-  String moduleName;
-  String name;
-  Pointer<WasmerFunctype> funcType;
-  WasmImportDescriptor(this.kind, this.moduleName, this.name, this.funcType);
-}
-
-class WasmExportDescriptor {
-  int kind;
-  String name;
-  Pointer<WasmerFunctype> funcType;
-  WasmExportDescriptor(this.kind, this.name, this.funcType);
-}
-
-class WasmRuntime {
-  static WasmRuntime? _inst;
-
-  DynamicLibrary _lib;
-  late Pointer<WasmerEngine> _engine;
-/* <RUNTIME_MEMB> */
-
-  factory WasmRuntime() {
-    WasmRuntime inst = _inst ?? WasmRuntime._init();
-    _inst = inst;
-    return inst;
-  }
-
-  static String _getLibName() {
-    if (Platform.isMacOS) return "libwasmer.dylib";
-    if (Platform.isLinux) return "libwasmer.so";
-    // TODO(dartbug.com/37882): Support more platforms.
-    throw Exception("Wasm not currently supported on this platform");
-  }
-
-  static String _getLibDir() {
-    // The common case, and how cli_util.dart computes the Dart SDK directory,
-    // path.dirname called twice on Platform.resolvedExecutable.
-    var commonLibDir = path.join(
-        path.absolute(path.dirname(path.dirname(Platform.resolvedExecutable))),
-        'bin',
-        'third_party',
-        'wasmer');
-    if (Directory(commonLibDir).existsSync()) {
-      return commonLibDir;
-    }
-
-    // This is the less common case where the user is in the checked out Dart
-    // SDK, and is executing dart via:
-    // ./out/ReleaseX64/dart ...
-    var checkedOutLibDir = path.join(
-        path.absolute(path.dirname(Platform.resolvedExecutable)),
-        'dart-sdk',
-        'bin',
-        'third_party',
-        'wasmer');
-    if (Directory(checkedOutLibDir).existsSync()) {
-      return checkedOutLibDir;
-    }
-
-    // If neither returned above, we return the common case:
-    return commonLibDir;
-  }
-
-  WasmRuntime._init()
-      : _lib = DynamicLibrary.open(path.join(_getLibDir(), _getLibName())) {
-/* <RUNTIME_LOAD> */
-
-    _engine = _engine_new();
-  }
-
-  Pointer<WasmerStore> newStore() {
-    return _store_new(_engine);
-  }
-
-  Pointer<WasmerModule> compile(Pointer<WasmerStore> store, Uint8List data) {
-    var dataPtr = allocate<Uint8>(count: data.length);
-    for (int i = 0; i < data.length; ++i) {
-      dataPtr[i] = data[i];
-    }
-    var dataVec = allocate<WasmerByteVec>();
-    dataVec.ref.data = dataPtr;
-    dataVec.ref.length = data.length;
-
-    var modulePtr = _module_new(store, dataVec);
-
-    free(dataPtr);
-    free(dataVec);
-
-    if (modulePtr == nullptr) {
-      throw Exception("Wasm module compile failed");
-    }
-
-    return modulePtr;
-  }
-
-  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
-    var exportsVec = allocate<WasmerExporttypeVec>();
-    _module_exports(module, exportsVec);
-    var exps = <WasmExportDescriptor>[];
-    for (var i = 0; i < exportsVec.ref.length; ++i) {
-      var exp = exportsVec.ref.data[i];
-      var extern = _exporttype_type(exp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      exps.add(WasmExportDescriptor(
-          kind, _exporttype_name(exp).ref.toString(), fnType));
-    }
-    free(exportsVec);
-    return exps;
-  }
-
-  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
-    var importsVec = allocate<WasmerImporttypeVec>();
-    _module_imports(module, importsVec);
-    var imps = <WasmImportDescriptor>[];
-    for (var i = 0; i < importsVec.ref.length; ++i) {
-      var imp = importsVec.ref.data[i];
-      var extern = _importtype_type(imp);
-      var kind = _externtype_kind(extern);
-      var fnType = kind == WasmerExternKindFunction
-          ? _externtype_as_functype(extern)
-          : nullptr;
-      imps.add(WasmImportDescriptor(
-          kind,
-          _importtype_module(imp).ref.toString(),
-          _importtype_name(imp).ref.toString(),
-          fnType));
-    }
-    free(importsVec);
-    return imps;
-  }
-
-  Pointer<WasmerInstance> instantiate(
-      Pointer<WasmerStore> store,
-      Pointer<WasmerModule> module,
-      Pointer<Pointer<WasmerExtern>> imports,
-      int numImports) {
-    var importsVec = allocate<WasmerImporttypeVec>();
-    _module_imports(module, importsVec);
-    if (importsVec.ref.length != numImports) {
-      throw Exception(
-          "Wrong number of imports. Expected ${importsVec.ref.length} but " +
-              "found $numImports.");
-    }
-    free(importsVec);
-
-    var instancePtr = _instance_new(store, module, imports, nullptr);
-    if (instancePtr == nullptr) {
-      throw Exception("Wasm module instantiation failed");
-    }
-
-    return instancePtr;
-  }
-
-  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
-    var exports = allocate<WasmerExternVec>();
-    _instance_exports(instancePtr, exports);
-    return exports;
-  }
-
-  int externKind(Pointer<WasmerExtern> extern) {
-    return _extern_kind(extern);
-  }
-
-  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) {
-    return _extern_as_func(extern);
-  }
-
-  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
-    var types = <int>[];
-    var args = _functype_params(funcType);
-    for (var i = 0; i < args.ref.length; ++i) {
-      types.add(_valtype_kind(args.ref.data[i]));
-    }
-    return types;
-  }
-
-  int getReturnType(Pointer<WasmerFunctype> funcType) {
-    var rets = _functype_results(funcType);
-    if (rets.ref.length == 0) {
-      return WasmerValKindVoid;
-    } else if (rets.ref.length > 1) {
-      throw Exception("Multiple return values are not supported");
-    }
-    return _valtype_kind(rets.ref.data[0]);
-  }
-
-  void call(Pointer<WasmerFunc> func, Pointer<WasmerVal> args,
-      Pointer<WasmerVal> results) {
-    _func_call(func, args, results);
-  }
-
-  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) {
-    return _extern_as_memory(extern);
-  }
-
-  Pointer<WasmerMemory> newMemory(
-      Pointer<WasmerStore> store, int pages, int? maxPages) {
-    var limPtr = allocate<WasmerLimits>();
-    limPtr.ref.min = pages;
-    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;
-  }
-
-  void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
-    var result = _memory_grow(memory, deltaPages);
-    if (result == 0) {
-      throw Exception("Failed to grow memory");
-    }
-  }
-
-  int memoryLength(Pointer<WasmerMemory> memory) {
-    return _memory_size(memory);
-  }
-
-  Uint8List memoryView(Pointer<WasmerMemory> memory) {
-    return _memory_data(memory).asTypedList(_memory_data_size(memory));
-  }
-}
diff --git a/pkg/wasm/lib/src/tools/wasmer_api_template.dart b/pkg/wasm/lib/src/tools/wasmer_api_template.dart
deleted file mode 100644
index 6a77171..0000000
--- a/pkg/wasm/lib/src/tools/wasmer_api_template.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/* <GEN_DOC> */
-
-import 'dart:convert';
-import 'dart:ffi';
-import 'dart:typed_data';
-
-// wasm_valkind_enum
-const int WasmerValKindI32 = 0;
-const int WasmerValKindI64 = 1;
-const int WasmerValKindF32 = 2;
-const int WasmerValKindF64 = 3;
-// The void tag is not part of the C API. It's used to represent the return type
-// of a void function.
-const int WasmerValKindVoid = -1;
-
-// wasm_externkind_enum
-const int WasmerExternKindFunction = 0;
-const int WasmerExternKindGlobal = 1;
-const int WasmerExternKindTable = 2;
-const int WasmerExternKindMemory = 3;
-
-String wasmerExternKindName(int kind) {
-  switch (kind) {
-    case WasmerExternKindFunction:
-      return "function";
-    case WasmerExternKindGlobal:
-      return "global";
-    case WasmerExternKindTable:
-      return "table";
-    case WasmerExternKindMemory:
-      return "memory";
-    default:
-      return "unknown";
-  }
-}
-
-String wasmerValKindName(int kind) {
-  switch (kind) {
-    case WasmerValKindI32:
-      return "int32";
-    case WasmerValKindI64:
-      return "int64";
-    case WasmerValKindF32:
-      return "float32";
-    case WasmerValKindF64:
-      return "float64";
-    case WasmerValKindVoid:
-      return "void";
-    default:
-      return "unknown";
-  }
-}
-
-// wasm_val_t
-class WasmerVal extends Struct {
-  // wasm_valkind_t
-  @Uint8()
-  external int kind;
-
-  // This is a union of int32_t, int64_t, float, and double. The kind determines
-  // which type it is. It's declared as an int64_t because that's large enough
-  // to hold all the types. We use ByteData to get the other types.
-  @Int64()
-  external int value;
-
-  int get _off32 => Endian.host == Endian.little ? 0 : 4;
-  int get i64 => value;
-  ByteData get _getterBytes => ByteData(8)..setInt64(0, value, Endian.host);
-  int get i32 => _getterBytes.getInt32(_off32, Endian.host);
-  double get f32 => _getterBytes.getFloat32(_off32, Endian.host);
-  double get f64 => _getterBytes.getFloat64(0, Endian.host);
-
-  set i64(int val) => value = val;
-  set _val(ByteData bytes) => value = bytes.getInt64(0, Endian.host);
-  set i32(int val) => _val = ByteData(8)..setInt32(_off32, val, Endian.host);
-  set f32(num val) =>
-      _val = ByteData(8)..setFloat32(_off32, val as double, Endian.host);
-  set f64(num val) =>
-      _val = ByteData(8)..setFloat64(0, val as double, Endian.host);
-
-  bool get isI32 => kind == WasmerValKindI32;
-  bool get isI64 => kind == WasmerValKindI64;
-  bool get isF32 => kind == WasmerValKindF32;
-  bool get isF64 => kind == WasmerValKindF64;
-}
-
-// wasmer_limits_t
-class WasmerLimits extends Struct {
-  @Uint32()
-  external int min;
-
-  @Uint32()
-  external int max;
-}
-
-// Default maximum, which indicates no upper limit.
-const int wasm_limits_max_default = 0xffffffff;
-
-/* <WASMER_API> */
diff --git a/pkg/wasm/lib/src/wasmer_api.dart b/pkg/wasm/lib/src/wasmer_api.dart
index ad8219d..94dd651 100644
--- a/pkg/wasm/lib/src/wasmer_api.dart
+++ b/pkg/wasm/lib/src/wasmer_api.dart
@@ -2,70 +2,116 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// This file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the following command
-// "generate_ffi_boilerplate.py".
-
 import 'dart:convert';
 import 'dart:ffi';
 import 'dart:typed_data';
 
-// wasm_valkind_enum
-const int WasmerValKindI32 = 0;
-const int WasmerValKindI64 = 1;
-const int WasmerValKindF32 = 2;
-const int WasmerValKindF64 = 3;
+// wasmer_result_t
+const int WasmerResultOk = 1;
+const int WasmerResultError = 2;
+
+// wasmer_value_tag
+const int WasmerValueTagI32 = 0;
+const int WasmerValueTagI64 = 1;
+const int WasmerValueTagF32 = 2;
+const int WasmerValueTagF64 = 3;
 // The void tag is not part of the C API. It's used to represent the return type
 // of a void function.
-const int WasmerValKindVoid = -1;
+const int WasmerValueTagVoid = -1;
 
-// wasm_externkind_enum
-const int WasmerExternKindFunction = 0;
-const int WasmerExternKindGlobal = 1;
-const int WasmerExternKindTable = 2;
-const int WasmerExternKindMemory = 3;
+// wasmer_import_export_kind
+const int WasmerImpExpKindFunction = 0;
+const int WasmerImpExpKindGlobal = 1;
+const int WasmerImpExpKindMemory = 2;
+const int WasmerImpExpKindTable = 3;
 
-String wasmerExternKindName(int kind) {
+String wasmerImpExpKindName(int kind) {
   switch (kind) {
-    case WasmerExternKindFunction:
+    case WasmerImpExpKindFunction:
       return "function";
-    case WasmerExternKindGlobal:
+    case WasmerImpExpKindGlobal:
       return "global";
-    case WasmerExternKindTable:
-      return "table";
-    case WasmerExternKindMemory:
+    case WasmerImpExpKindMemory:
       return "memory";
+    case WasmerImpExpKindTable:
+      return "table";
     default:
       return "unknown";
   }
 }
 
-String wasmerValKindName(int kind) {
-  switch (kind) {
-    case WasmerValKindI32:
-      return "int32";
-    case WasmerValKindI64:
-      return "int64";
-    case WasmerValKindF32:
-      return "float32";
-    case WasmerValKindF64:
-      return "float64";
-    case WasmerValKindVoid:
-      return "void";
-    default:
-      return "unknown";
-  }
+// wasmer_module_t
+class WasmerModule extends Struct {}
+
+// wasmer_instance_t
+class WasmerInstance extends Struct {}
+
+// wasmer_exports_t
+class WasmerExports extends Struct {}
+
+// wasmer_export_t
+class WasmerExport extends Struct {}
+
+// wasmer_export_descriptors_t
+class WasmerExportDescriptors extends Struct {}
+
+// wasmer_export_descriptor_t
+class WasmerExportDescriptor extends Struct {}
+
+// wasmer_export_func_t
+class WasmerExportFunc extends Struct {}
+
+// wasmer_import_descriptors_t
+class WasmerImportDescriptors extends Struct {}
+
+// wasmer_import_descriptor_t
+class WasmerImportDescriptor extends Struct {}
+
+// wasmer_memory_t
+class WasmerMemory extends Struct {}
+
+// wasmer_import_t
+class WasmerImport extends Struct {
+  external Pointer<Uint8> module_name;
+
+  @Uint32()
+  external int module_name_length;
+
+  external Pointer<Uint8> import_name;
+
+  @Uint32()
+  external int import_name_length;
+
+  // wasmer_import_export_kind
+  @Uint32()
+  external int tag;
+
+  // wasmer_import_export_value, which is a union of wasmer_import_func_t*,
+  // wasmer_table_t*, wasmer_memory_t*, and wasmer_global_t*. The tag determines
+  // which type it is.
+  external Pointer<Void> value;
 }
 
-// wasm_val_t
-class WasmerVal extends Struct {
-  // wasm_valkind_t
-  @Uint8()
-  external int kind;
+// wasmer_byte_array
+class WasmerByteArray extends Struct {
+  external Pointer<Uint8> bytes;
 
-  // This is a union of int32_t, int64_t, float, and double. The kind determines
-  // which type it is. It's declared as an int64_t because that's large enough
-  // to hold all the types. We use ByteData to get the other types.
+  @Uint32()
+  external int length;
+
+  Uint8List get list => bytes.asTypedList(length);
+  String get string => utf8.decode(list);
+}
+
+// wasmer_value_t
+class WasmerValue extends Struct {
+  // wasmer_value_tag
+  @Uint32()
+  external int tag;
+
+  // wasmer_value, which is a union of int32_t, int64_t, float, and double. The
+  // tag determines which type it is. It's declared as an int64_t because that's
+  // large enough to hold all the types. We use ByteData to get the other types.
   @Int64()
   external int value;
 
@@ -84,10 +130,10 @@
   set f64(num val) =>
       _val = ByteData(8)..setFloat64(0, val as double, Endian.host);
 
-  bool get isI32 => kind == WasmerValKindI32;
-  bool get isI64 => kind == WasmerValKindI64;
-  bool get isF32 => kind == WasmerValKindF32;
-  bool get isF64 => kind == WasmerValKindF64;
+  bool get isI32 => tag == WasmerValueTagI32;
+  bool get isI64 => tag == WasmerValueTagI64;
+  bool get isF32 => tag == WasmerValueTagF32;
+  bool get isF64 => tag == WasmerValueTagF64;
 }
 
 // wasmer_limits_t
@@ -95,417 +141,196 @@
   @Uint32()
   external int min;
 
+  // bool
+  @Uint8()
+  external int has_max;
+
   @Uint32()
   external int max;
 }
 
-// Default maximum, which indicates no upper limit.
-const int wasm_limits_max_default = 0xffffffff;
+// wasmer_compile
+typedef NativeWasmerCompileFn = Uint32 Function(
+    Pointer<Pointer<WasmerModule>>, Pointer<Uint8>, Uint32);
+typedef WasmerCompileFn = int Function(
+    Pointer<Pointer<WasmerModule>>, Pointer<Uint8>, int);
 
-// wasm_engine_t
-class WasmerEngine extends Struct {}
+// wasmer_module_instantiate
+typedef NativeWasmerInstantiateFn = Uint32 Function(Pointer<WasmerModule>,
+    Pointer<Pointer<WasmerInstance>>, Pointer<WasmerImport>, Int32);
+typedef WasmerInstantiateFn = int Function(Pointer<WasmerModule>,
+    Pointer<Pointer<WasmerInstance>>, Pointer<WasmerImport>, int);
 
-// wasm_exporttype_t
-class WasmerExporttype extends Struct {}
-
-// wasm_extern_t
-class WasmerExtern extends Struct {}
-
-// wasm_externtype_t
-class WasmerExterntype extends Struct {}
-
-// wasm_func_t
-class WasmerFunc extends Struct {}
-
-// wasm_functype_t
-class WasmerFunctype extends Struct {}
-
-// wasm_importtype_t
-class WasmerImporttype extends Struct {}
-
-// wasm_instance_t
-class WasmerInstance extends Struct {}
-
-// wasm_memory_t
-class WasmerMemory extends Struct {}
-
-// wasm_memorytype_t
-class WasmerMemorytype extends Struct {}
-
-// wasm_module_t
-class WasmerModule extends Struct {}
-
-// wasm_store_t
-class WasmerStore extends Struct {}
-
-// wasm_trap_t
-class WasmerTrap extends Struct {}
-
-// wasm_valtype_t
-class WasmerValtype extends Struct {}
-
-// wasm_byte_vec_t
-class WasmerByteVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Uint8> data;
-
-  Uint8List get list => data.asTypedList(length);
-  String toString() => utf8.decode(list);
-}
-
-// wasm_exporttype_vec_t
-class WasmerExporttypeVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerExporttype>> data;
-}
-
-// wasm_extern_vec_t
-class WasmerExternVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerExtern>> data;
-}
-
-// wasm_importtype_vec_t
-class WasmerImporttypeVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerImporttype>> data;
-}
-
-// wasm_val_vec_t
-class WasmerValVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<WasmerVal> data;
-}
-
-// wasm_valtype_vec_t
-class WasmerValtypeVec extends Struct {
-  @Uint64()
-  external int length;
-
-  external Pointer<Pointer<WasmerValtype>> data;
-}
-
-// wasm_byte_vec_delete
-typedef NativeWasmerByteVecDeleteFn = Void Function(Pointer<WasmerByteVec>);
-typedef WasmerByteVecDeleteFn = void Function(Pointer<WasmerByteVec>);
-
-// wasm_byte_vec_new
-typedef NativeWasmerByteVecNewFn = Void Function(
-    Pointer<WasmerByteVec>, Uint64, Pointer<Uint8>);
-typedef WasmerByteVecNewFn = void Function(
-    Pointer<WasmerByteVec>, int, Pointer<Uint8>);
-
-// wasm_byte_vec_new_empty
-typedef NativeWasmerByteVecNewEmptyFn = Void Function(Pointer<WasmerByteVec>);
-typedef WasmerByteVecNewEmptyFn = void Function(Pointer<WasmerByteVec>);
-
-// wasm_byte_vec_new_uninitialized
-typedef NativeWasmerByteVecNewUninitializedFn = Void Function(
-    Pointer<WasmerByteVec>, Uint64);
-typedef WasmerByteVecNewUninitializedFn = void Function(
-    Pointer<WasmerByteVec>, int);
-
-// wasm_engine_delete
-typedef NativeWasmerEngineDeleteFn = Void Function(Pointer<WasmerEngine>);
-typedef WasmerEngineDeleteFn = void Function(Pointer<WasmerEngine>);
-
-// wasm_engine_new
-typedef NativeWasmerEngineNewFn = Pointer<WasmerEngine> Function();
-typedef WasmerEngineNewFn = Pointer<WasmerEngine> Function();
-
-// wasm_exporttype_name
-typedef NativeWasmerExporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerExporttype>);
-typedef WasmerExporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerExporttype>);
-
-// wasm_exporttype_type
-typedef NativeWasmerExporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerExporttype>);
-typedef WasmerExporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerExporttype>);
-
-// wasm_exporttype_vec_delete
-typedef NativeWasmerExporttypeVecDeleteFn = Void Function(
-    Pointer<WasmerExporttypeVec>);
-typedef WasmerExporttypeVecDeleteFn = void Function(
-    Pointer<WasmerExporttypeVec>);
-
-// wasm_exporttype_vec_new
-typedef NativeWasmerExporttypeVecNewFn = Void Function(
-    Pointer<WasmerExporttypeVec>, Uint64, Pointer<Pointer<WasmerExporttype>>);
-typedef WasmerExporttypeVecNewFn = void Function(
-    Pointer<WasmerExporttypeVec>, int, Pointer<Pointer<WasmerExporttype>>);
-
-// wasm_exporttype_vec_new_empty
-typedef NativeWasmerExporttypeVecNewEmptyFn = Void Function(
-    Pointer<WasmerExporttypeVec>);
-typedef WasmerExporttypeVecNewEmptyFn = void Function(
-    Pointer<WasmerExporttypeVec>);
-
-// wasm_exporttype_vec_new_uninitialized
-typedef NativeWasmerExporttypeVecNewUninitializedFn = Void Function(
-    Pointer<WasmerExporttypeVec>, Uint64);
-typedef WasmerExporttypeVecNewUninitializedFn = void Function(
-    Pointer<WasmerExporttypeVec>, int);
-
-// wasm_extern_as_func
-typedef NativeWasmerExternAsFuncFn = Pointer<WasmerFunc> Function(
-    Pointer<WasmerExtern>);
-typedef WasmerExternAsFuncFn = Pointer<WasmerFunc> Function(
-    Pointer<WasmerExtern>);
-
-// wasm_extern_as_memory
-typedef NativeWasmerExternAsMemoryFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerExtern>);
-typedef WasmerExternAsMemoryFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerExtern>);
-
-// wasm_extern_delete
-typedef NativeWasmerExternDeleteFn = Void Function(Pointer<WasmerExtern>);
-typedef WasmerExternDeleteFn = void Function(Pointer<WasmerExtern>);
-
-// wasm_extern_kind
-typedef NativeWasmerExternKindFn = Uint8 Function(Pointer<WasmerExtern>);
-typedef WasmerExternKindFn = int Function(Pointer<WasmerExtern>);
-
-// wasm_extern_vec_delete
-typedef NativeWasmerExternVecDeleteFn = Void Function(Pointer<WasmerExternVec>);
-typedef WasmerExternVecDeleteFn = void Function(Pointer<WasmerExternVec>);
-
-// wasm_extern_vec_new
-typedef NativeWasmerExternVecNewFn = Void Function(
-    Pointer<WasmerExternVec>, Uint64, Pointer<Pointer<WasmerExtern>>);
-typedef WasmerExternVecNewFn = void Function(
-    Pointer<WasmerExternVec>, int, Pointer<Pointer<WasmerExtern>>);
-
-// wasm_extern_vec_new_empty
-typedef NativeWasmerExternVecNewEmptyFn = Void Function(
-    Pointer<WasmerExternVec>);
-typedef WasmerExternVecNewEmptyFn = void Function(Pointer<WasmerExternVec>);
-
-// wasm_extern_vec_new_uninitialized
-typedef NativeWasmerExternVecNewUninitializedFn = Void Function(
-    Pointer<WasmerExternVec>, Uint64);
-typedef WasmerExternVecNewUninitializedFn = void Function(
-    Pointer<WasmerExternVec>, int);
-
-// wasm_externtype_as_functype
-typedef NativeWasmerExterntypeAsFunctypeFn = Pointer<WasmerFunctype> Function(
-    Pointer<WasmerExterntype>);
-typedef WasmerExterntypeAsFunctypeFn = Pointer<WasmerFunctype> Function(
-    Pointer<WasmerExterntype>);
-
-// wasm_externtype_delete
-typedef NativeWasmerExterntypeDeleteFn = Void Function(
-    Pointer<WasmerExterntype>);
-typedef WasmerExterntypeDeleteFn = void Function(Pointer<WasmerExterntype>);
-
-// wasm_externtype_kind
-typedef NativeWasmerExterntypeKindFn = Uint8 Function(
-    Pointer<WasmerExterntype>);
-typedef WasmerExterntypeKindFn = int Function(Pointer<WasmerExterntype>);
-
-// wasm_func_call
-typedef NativeWasmerFuncCallFn = Pointer<WasmerTrap> Function(
-    Pointer<WasmerFunc>, Pointer<WasmerVal>, Pointer<WasmerVal>);
-typedef WasmerFuncCallFn = Pointer<WasmerTrap> Function(
-    Pointer<WasmerFunc>, Pointer<WasmerVal>, Pointer<WasmerVal>);
-
-// wasm_func_delete
-typedef NativeWasmerFuncDeleteFn = Void Function(Pointer<WasmerFunc>);
-typedef WasmerFuncDeleteFn = void Function(Pointer<WasmerFunc>);
-
-// wasm_functype_delete
-typedef NativeWasmerFunctypeDeleteFn = Void Function(Pointer<WasmerFunctype>);
-typedef WasmerFunctypeDeleteFn = void Function(Pointer<WasmerFunctype>);
-
-// wasm_functype_params
-typedef NativeWasmerFunctypeParamsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-typedef WasmerFunctypeParamsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-
-// wasm_functype_results
-typedef NativeWasmerFunctypeResultsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-typedef WasmerFunctypeResultsFn = Pointer<WasmerValtypeVec> Function(
-    Pointer<WasmerFunctype>);
-
-// wasm_importtype_module
-typedef NativeWasmerImporttypeModuleFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-typedef WasmerImporttypeModuleFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-
-// wasm_importtype_name
-typedef NativeWasmerImporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-typedef WasmerImporttypeNameFn = Pointer<WasmerByteVec> Function(
-    Pointer<WasmerImporttype>);
-
-// wasm_importtype_type
-typedef NativeWasmerImporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerImporttype>);
-typedef WasmerImporttypeTypeFn = Pointer<WasmerExterntype> Function(
-    Pointer<WasmerImporttype>);
-
-// wasm_importtype_vec_delete
-typedef NativeWasmerImporttypeVecDeleteFn = Void Function(
-    Pointer<WasmerImporttypeVec>);
-typedef WasmerImporttypeVecDeleteFn = void Function(
-    Pointer<WasmerImporttypeVec>);
-
-// wasm_importtype_vec_new
-typedef NativeWasmerImporttypeVecNewFn = Void Function(
-    Pointer<WasmerImporttypeVec>, Uint64, Pointer<Pointer<WasmerImporttype>>);
-typedef WasmerImporttypeVecNewFn = void Function(
-    Pointer<WasmerImporttypeVec>, int, Pointer<Pointer<WasmerImporttype>>);
-
-// wasm_importtype_vec_new_empty
-typedef NativeWasmerImporttypeVecNewEmptyFn = Void Function(
-    Pointer<WasmerImporttypeVec>);
-typedef WasmerImporttypeVecNewEmptyFn = void Function(
-    Pointer<WasmerImporttypeVec>);
-
-// wasm_importtype_vec_new_uninitialized
-typedef NativeWasmerImporttypeVecNewUninitializedFn = Void Function(
-    Pointer<WasmerImporttypeVec>, Uint64);
-typedef WasmerImporttypeVecNewUninitializedFn = void Function(
-    Pointer<WasmerImporttypeVec>, int);
-
-// wasm_instance_delete
-typedef NativeWasmerInstanceDeleteFn = Void Function(Pointer<WasmerInstance>);
-typedef WasmerInstanceDeleteFn = void Function(Pointer<WasmerInstance>);
-
-// wasm_instance_exports
+// wasmer_instance_exports
 typedef NativeWasmerInstanceExportsFn = Void Function(
-    Pointer<WasmerInstance>, Pointer<WasmerExternVec>);
+    Pointer<WasmerInstance>, Pointer<Pointer<WasmerExports>>);
 typedef WasmerInstanceExportsFn = void Function(
-    Pointer<WasmerInstance>, Pointer<WasmerExternVec>);
+    Pointer<WasmerInstance>, Pointer<Pointer<WasmerExports>>);
 
-// wasm_instance_new
-typedef NativeWasmerInstanceNewFn = Pointer<WasmerInstance> Function(
-    Pointer<WasmerStore>,
-    Pointer<WasmerModule>,
-    Pointer<Pointer<WasmerExtern>>,
-    Pointer<Pointer<WasmerTrap>>);
-typedef WasmerInstanceNewFn = Pointer<WasmerInstance> Function(
-    Pointer<WasmerStore>,
-    Pointer<WasmerModule>,
-    Pointer<Pointer<WasmerExtern>>,
-    Pointer<Pointer<WasmerTrap>>);
+// wasmer_exports_len
+typedef NativeWasmerExportsLenFn = Int32 Function(Pointer<WasmerExports>);
+typedef WasmerExportsLenFn = int Function(Pointer<WasmerExports>);
 
-// wasm_memory_data
+// wasmer_exports_get
+typedef NativeWasmerExportsGetFn = Pointer<WasmerExport> Function(
+    Pointer<WasmerExports>, Int32);
+typedef WasmerExportsGetFn = Pointer<WasmerExport> Function(
+    Pointer<WasmerExports>, int);
+
+// wasmer_export_descriptors
+typedef NativeWasmerExportDescriptorsFn = Void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerExportDescriptors>>);
+typedef WasmerExportDescriptorsFn = void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerExportDescriptors>>);
+
+// wasmer_export_descriptors_destroy
+typedef NativeWasmerExportDescriptorsDestroyFn = Void Function(
+    Pointer<WasmerExportDescriptors>);
+typedef WasmerExportDescriptorsDestroyFn = void Function(
+    Pointer<WasmerExportDescriptors>);
+
+// wasmer_export_descriptors_len
+typedef NativeWasmerExportDescriptorsLenFn = Int32 Function(
+    Pointer<WasmerExportDescriptors>);
+typedef WasmerExportDescriptorsLenFn = int Function(
+    Pointer<WasmerExportDescriptors>);
+
+// wasmer_export_descriptors_get
+typedef NativeWasmerExportDescriptorsGetFn = Pointer<WasmerExportDescriptor>
+    Function(Pointer<WasmerExportDescriptors>, Int32);
+typedef WasmerExportDescriptorsGetFn = Pointer<WasmerExportDescriptor> Function(
+    Pointer<WasmerExportDescriptors>, int);
+
+// wasmer_export_descriptor_kind
+typedef NativeWasmerExportDescriptorKindFn = Uint32 Function(
+    Pointer<WasmerExportDescriptor>);
+typedef WasmerExportDescriptorKindFn = int Function(
+    Pointer<WasmerExportDescriptor>);
+
+// wasmer_export_descriptor_name_ptr
+typedef NativeWasmerExportDescriptorNamePtrFn = Void Function(
+    Pointer<WasmerExportDescriptor>, Pointer<WasmerByteArray>);
+typedef WasmerExportDescriptorNamePtrFn = void Function(
+    Pointer<WasmerExportDescriptor>, Pointer<WasmerByteArray>);
+
+// wasmer_import_descriptors
+typedef NativeWasmerImportDescriptorsFn = Void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerImportDescriptors>>);
+typedef WasmerImportDescriptorsFn = void Function(
+    Pointer<WasmerModule>, Pointer<Pointer<WasmerImportDescriptors>>);
+
+// wasmer_import_descriptors_destroy
+typedef NativeWasmerImportDescriptorsDestroyFn = Void Function(
+    Pointer<WasmerImportDescriptors>);
+typedef WasmerImportDescriptorsDestroyFn = void Function(
+    Pointer<WasmerImportDescriptors>);
+
+// wasmer_import_descriptors_len
+typedef NativeWasmerImportDescriptorsLenFn = Int32 Function(
+    Pointer<WasmerImportDescriptors>);
+typedef WasmerImportDescriptorsLenFn = int Function(
+    Pointer<WasmerImportDescriptors>);
+
+// wasmer_import_descriptors_get
+typedef NativeWasmerImportDescriptorsGetFn = Pointer<WasmerImportDescriptor>
+    Function(Pointer<WasmerImportDescriptors>, Int32);
+typedef WasmerImportDescriptorsGetFn = Pointer<WasmerImportDescriptor> Function(
+    Pointer<WasmerImportDescriptors>, int);
+
+// wasmer_import_descriptor_kind
+typedef NativeWasmerImportDescriptorKindFn = Uint32 Function(
+    Pointer<WasmerImportDescriptor>);
+typedef WasmerImportDescriptorKindFn = int Function(
+    Pointer<WasmerImportDescriptor>);
+
+// wasmer_import_descriptor_module_name_ptr
+typedef NativeWasmerImportDescriptorModuleNamePtrFn = Void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+typedef WasmerImportDescriptorModuleNamePtrFn = void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+
+// wasmer_import_descriptor_name_ptr
+typedef NativeWasmerImportDescriptorNamePtrFn = Void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+typedef WasmerImportDescriptorNamePtrFn = void Function(
+    Pointer<WasmerImportDescriptor>, Pointer<WasmerByteArray>);
+
+// wasmer_export_name_ptr
+typedef NativeWasmerExportNamePtrFn = Void Function(
+    Pointer<WasmerExport>, Pointer<WasmerByteArray>);
+typedef WasmerExportNamePtrFn = void Function(
+    Pointer<WasmerExport>, Pointer<WasmerByteArray>);
+
+// wasmer_export_kind
+typedef NativeWasmerExportKindFn = Uint32 Function(Pointer<WasmerExport>);
+typedef WasmerExportKindFn = int Function(Pointer<WasmerExport>);
+
+// wasmer_export_to_func
+typedef NativeWasmerExportToFuncFn = Pointer<WasmerExportFunc> Function(
+    Pointer<WasmerExport>);
+typedef WasmerExportToFuncFn = Pointer<WasmerExportFunc> Function(
+    Pointer<WasmerExport>);
+
+// wasmer_export_func_returns_arity
+typedef NativeWasmerExportFuncReturnsArityFn = Uint32 Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>);
+typedef WasmerExportFuncReturnsArityFn = int Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>);
+
+// wasmer_export_func_returns
+typedef NativeWasmerExportFuncReturnsFn = Uint32 Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>, Uint32);
+typedef WasmerExportFuncReturnsFn = int Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>, int);
+
+// wasmer_export_func_params_arity
+typedef NativeWasmerExportFuncParamsArityFn = Uint32 Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>);
+typedef WasmerExportFuncParamsArityFn = int Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>);
+
+// wasmer_export_func_params
+typedef NativeWasmerExportFuncParamsFn = Uint32 Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>, Uint32);
+typedef WasmerExportFuncParamsFn = int Function(
+    Pointer<WasmerExportFunc>, Pointer<Uint32>, int);
+
+// wasmer_export_func_call
+typedef NativeWasmerExportFuncCallFn = Uint32 Function(
+    Pointer<WasmerExportFunc>,
+    Pointer<WasmerValue>,
+    Uint32,
+    Pointer<WasmerValue>,
+    Uint32);
+typedef WasmerExportFuncCallFn = int Function(Pointer<WasmerExportFunc>,
+    Pointer<WasmerValue>, int, Pointer<WasmerValue>, int);
+
+// wasmer_export_to_memory
+typedef NativeWasmerExportToMemoryFn = Uint32 Function(
+    Pointer<WasmerExport>, Pointer<Pointer<WasmerMemory>>);
+typedef WasmerExportToMemoryFn = int Function(
+    Pointer<WasmerExport>, Pointer<Pointer<WasmerMemory>>);
+
+// wasmer_memory_new_ptr
+typedef NativeWasmerMemoryNewPtrFn = Uint32 Function(
+    Pointer<Pointer<WasmerMemory>>, Pointer<WasmerLimits>);
+typedef WasmerMemoryNewPtrFn = int Function(
+    Pointer<Pointer<WasmerMemory>>, Pointer<WasmerLimits>);
+
+// wasmer_memory_grow
+typedef NativeWasmerMemoryGrowFn = Uint32 Function(
+    Pointer<WasmerMemory>, Uint32);
+typedef WasmerMemoryGrowFn = int Function(Pointer<WasmerMemory>, int);
+
+// wasmer_memory_length
+typedef NativeWasmerMemoryLengthFn = Uint32 Function(Pointer<WasmerMemory>);
+typedef WasmerMemoryLengthFn = int Function(Pointer<WasmerMemory>);
+
+// wasmer_memory_data
 typedef NativeWasmerMemoryDataFn = Pointer<Uint8> Function(
     Pointer<WasmerMemory>);
 typedef WasmerMemoryDataFn = Pointer<Uint8> Function(Pointer<WasmerMemory>);
 
-// wasm_memory_data_size
-typedef NativeWasmerMemoryDataSizeFn = Uint64 Function(Pointer<WasmerMemory>);
-typedef WasmerMemoryDataSizeFn = int Function(Pointer<WasmerMemory>);
-
-// wasm_memory_delete
-typedef NativeWasmerMemoryDeleteFn = Void Function(Pointer<WasmerMemory>);
-typedef WasmerMemoryDeleteFn = void Function(Pointer<WasmerMemory>);
-
-// wasm_memory_grow
-typedef NativeWasmerMemoryGrowFn = Uint8 Function(
-    Pointer<WasmerMemory>, Uint32);
-typedef WasmerMemoryGrowFn = int Function(Pointer<WasmerMemory>, int);
-
-// wasm_memory_new
-typedef NativeWasmerMemoryNewFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerStore>, Pointer<WasmerMemorytype>);
-typedef WasmerMemoryNewFn = Pointer<WasmerMemory> Function(
-    Pointer<WasmerStore>, Pointer<WasmerMemorytype>);
-
-// wasm_memory_size
-typedef NativeWasmerMemorySizeFn = Uint32 Function(Pointer<WasmerMemory>);
-typedef WasmerMemorySizeFn = int Function(Pointer<WasmerMemory>);
-
-// wasm_memorytype_delete
-typedef NativeWasmerMemorytypeDeleteFn = Void Function(
-    Pointer<WasmerMemorytype>);
-typedef WasmerMemorytypeDeleteFn = void Function(Pointer<WasmerMemorytype>);
-
-// wasm_memorytype_new
-typedef NativeWasmerMemorytypeNewFn = Pointer<WasmerMemorytype> Function(
-    Pointer<WasmerLimits>);
-typedef WasmerMemorytypeNewFn = Pointer<WasmerMemorytype> Function(
-    Pointer<WasmerLimits>);
-
-// wasm_module_delete
-typedef NativeWasmerModuleDeleteFn = Void Function(Pointer<WasmerModule>);
-typedef WasmerModuleDeleteFn = void Function(Pointer<WasmerModule>);
-
-// wasm_module_exports
-typedef NativeWasmerModuleExportsFn = Void Function(
-    Pointer<WasmerModule>, Pointer<WasmerExporttypeVec>);
-typedef WasmerModuleExportsFn = void Function(
-    Pointer<WasmerModule>, Pointer<WasmerExporttypeVec>);
-
-// wasm_module_imports
-typedef NativeWasmerModuleImportsFn = Void Function(
-    Pointer<WasmerModule>, Pointer<WasmerImporttypeVec>);
-typedef WasmerModuleImportsFn = void Function(
-    Pointer<WasmerModule>, Pointer<WasmerImporttypeVec>);
-
-// wasm_module_new
-typedef NativeWasmerModuleNewFn = Pointer<WasmerModule> Function(
-    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
-typedef WasmerModuleNewFn = Pointer<WasmerModule> Function(
-    Pointer<WasmerStore>, Pointer<WasmerByteVec>);
-
-// wasm_store_delete
-typedef NativeWasmerStoreDeleteFn = Void Function(Pointer<WasmerStore>);
-typedef WasmerStoreDeleteFn = void Function(Pointer<WasmerStore>);
-
-// wasm_store_new
-typedef NativeWasmerStoreNewFn = Pointer<WasmerStore> Function(
-    Pointer<WasmerEngine>);
-typedef WasmerStoreNewFn = Pointer<WasmerStore> Function(Pointer<WasmerEngine>);
-
-// wasm_trap_delete
-typedef NativeWasmerTrapDeleteFn = Void Function(Pointer<WasmerTrap>);
-typedef WasmerTrapDeleteFn = void Function(Pointer<WasmerTrap>);
-
-// wasm_valtype_delete
-typedef NativeWasmerValtypeDeleteFn = Void Function(Pointer<WasmerValtype>);
-typedef WasmerValtypeDeleteFn = void Function(Pointer<WasmerValtype>);
-
-// wasm_valtype_kind
-typedef NativeWasmerValtypeKindFn = Uint8 Function(Pointer<WasmerValtype>);
-typedef WasmerValtypeKindFn = int Function(Pointer<WasmerValtype>);
-
-// wasm_valtype_vec_delete
-typedef NativeWasmerValtypeVecDeleteFn = Void Function(
-    Pointer<WasmerValtypeVec>);
-typedef WasmerValtypeVecDeleteFn = void Function(Pointer<WasmerValtypeVec>);
-
-// wasm_valtype_vec_new
-typedef NativeWasmerValtypeVecNewFn = Void Function(
-    Pointer<WasmerValtypeVec>, Uint64, Pointer<Pointer<WasmerValtype>>);
-typedef WasmerValtypeVecNewFn = void Function(
-    Pointer<WasmerValtypeVec>, int, Pointer<Pointer<WasmerValtype>>);
-
-// wasm_valtype_vec_new_empty
-typedef NativeWasmerValtypeVecNewEmptyFn = Void Function(
-    Pointer<WasmerValtypeVec>);
-typedef WasmerValtypeVecNewEmptyFn = void Function(Pointer<WasmerValtypeVec>);
-
-// wasm_valtype_vec_new_uninitialized
-typedef NativeWasmerValtypeVecNewUninitializedFn = Void Function(
-    Pointer<WasmerValtypeVec>, Uint64);
-typedef WasmerValtypeVecNewUninitializedFn = void Function(
-    Pointer<WasmerValtypeVec>, int);
+// wasmer_memory_data_length
+typedef NativeWasmerMemoryDataLengthFn = Uint32 Function(Pointer<WasmerMemory>);
+typedef WasmerMemoryDataLengthFn = int Function(Pointer<WasmerMemory>);
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 392c905..9444e50 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -586,17 +586,16 @@
   visibility = [ ":create_common_sdk" ]
   deps = [
     ":copy_libraries",
-    "../third_party/wasmer:wasmer",
+    "../third_party/wasmer:wasmer_wrapper",
   ]
   outputs =
       [ "$root_out_dir/dart-sdk/bin/third_party/wasmer/{{source_file_part}}" ]
   if (is_win) {
-    sources = [ "$target_out_dir/../third_party/wasmer/wasmer.dll" ]
+    sources = [ "$root_out_dir/wasmer_wrapper.dll" ]
   } else if (is_mac) {
-    sources = [ "$target_out_dir/../third_party/wasmer/libwasmer.dylib" ]
+    sources = [ "$root_out_dir/libwasmer_wrapper.dylib" ]
   } else {
-    # TODO(dartbug.com/37882): Support Fuchsia.
-    sources = [ "$target_out_dir/../third_party/wasmer/libwasmer.so" ]
+    sources = [ "$root_out_dir/libwasmer_wrapper.so" ]
   }
 }
 
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index f764342..8970fe8 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -26,11 +26,13 @@
 Language/Statements/Expression_Statements/syntax_t06: Skip # Type aliases are not fully implemented
 Language/Types/Type_Aliases/built-in_types_t11: Skip # Triple shift is not implemented yet
 LanguageFeatures/Extension-methods/explicit_extension_member_invocation_A15_t09: Skip # Triple shift is not implemented yet
-LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # Not migrated to NNBD
-LanguageFeatures/Instantiate-to-bound/typedef/static/*: Skip # Not migrated to NNBD
+LanguageFeatures/Instantiate-to-bound/nonfunction_typedef/static/*: Skip # Type aliases are not fully implemented
 LanguageFeatures/Simple-bounds/dynamic/type-aliases/*: Skip # Type aliases are not fully implemented
 LanguageFeatures/Simple-bounds/static/type-aliases/*: Skip # Type aliases are not fully implemented
 LanguageFeatures/Triple-Shift/*: Skip # Triple shift is not implemented yet
+LanguageFeatures/nnbd/local_variable_read_A01_t03: Skip # Triple shift is not implemented yet
+LanguageFeatures/nnbd/local_variable_read_A02_t03: Skip # Triple shift is not implemented yet
+LanguageFeatures/nnbd/local_variable_read_A03_t03: Skip # Triple shift is not implemented yet
 LanguageFeatures/regression/34560_t02/01: Skip # Type aliases are not fully implemented
 LibTest/io/RawDatagramSocket/*: Skip # https://github.com/dart-lang/co19/issues/195
 
diff --git a/tests/lib/wasm/memory_error_test.dart b/tests/lib/wasm/memory_error_test.dart
index f02dc6c..3a172d8 100644
--- a/tests/lib/wasm/memory_error_test.dart
+++ b/tests/lib/wasm/memory_error_test.dart
@@ -9,14 +9,9 @@
 import "dart:typed_data";
 
 void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  Expect.throws(() => module.createMemory(1000000000));
-  var mem = module.createMemory(100);
+  Expect.throws(() => WasmMemory(1000000000));
+  var mem = WasmMemory(100);
   Expect.throws(() => mem.grow(1000000000));
-  mem = module.createMemory(100, 200);
+  mem = WasmMemory(100, 200);
   Expect.throws(() => mem.grow(300));
 }
diff --git a/tests/lib/wasm/memory_test.dart b/tests/lib/wasm/memory_test.dart
index 544c6a1..ecaf433 100644
--- a/tests/lib/wasm/memory_test.dart
+++ b/tests/lib/wasm/memory_test.dart
@@ -9,12 +9,7 @@
 import "dart:typed_data";
 
 void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  var mem = module.createMemory(100);
+  var mem = WasmMemory(100);
   Expect.equals(100, mem.lengthInPages);
   Expect.equals(100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
 
diff --git a/tests/lib_2/wasm/basic_test.dart b/tests/lib_2/wasm/basic_test.dart
index da2fb9a..72f4c6c 100644
--- a/tests/lib_2/wasm/basic_test.dart
+++ b/tests/lib_2/wasm/basic_test.dart
@@ -22,7 +22,7 @@
 
   var inst = WasmModule(data).instantiate(WasmImports());
   var fn = inst.lookupFunction("square");
-  int n = fn(1234);
+  int n = fn.call(1234);
 
   Expect.equals(1234 * 1234, n);
 
diff --git a/tests/lib_2/wasm/memory_error_test.dart b/tests/lib_2/wasm/memory_error_test.dart
index f02dc6c..3a172d8 100644
--- a/tests/lib_2/wasm/memory_error_test.dart
+++ b/tests/lib_2/wasm/memory_error_test.dart
@@ -9,14 +9,9 @@
 import "dart:typed_data";
 
 void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  Expect.throws(() => module.createMemory(1000000000));
-  var mem = module.createMemory(100);
+  Expect.throws(() => WasmMemory(1000000000));
+  var mem = WasmMemory(100);
   Expect.throws(() => mem.grow(1000000000));
-  mem = module.createMemory(100, 200);
+  mem = WasmMemory(100, 200);
   Expect.throws(() => mem.grow(300));
 }
diff --git a/tests/lib_2/wasm/memory_test.dart b/tests/lib_2/wasm/memory_test.dart
index 544c6a1..ecaf433 100644
--- a/tests/lib_2/wasm/memory_test.dart
+++ b/tests/lib_2/wasm/memory_test.dart
@@ -9,12 +9,7 @@
 import "dart:typed_data";
 
 void main() {
-  // Empty wasm module.
-  var data = Uint8List.fromList(
-      [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x00, 0x00]);
-  var module = WasmModule(data);
-
-  var mem = module.createMemory(100);
+  var mem = WasmMemory(100);
   Expect.equals(100, mem.lengthInPages);
   Expect.equals(100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
 
diff --git a/third_party/wasmer/BUILD.gn b/third_party/wasmer/BUILD.gn
index f3398f5..afd36a8 100644
--- a/third_party/wasmer/BUILD.gn
+++ b/third_party/wasmer/BUILD.gn
@@ -1,6 +1,17 @@
 import("../../build/rust/rust.gni")
 
-rust_library("wasmer") {
+shared_library("wasmer_wrapper") {
+  sources = [
+    "wasmer.hh",
+    "wasmer_wrapper.cc",
+  ]
+  deps = [ ":wasmer_lib" ]
+  if (is_linux) {
+    libs = [ "rt" ]
+  }
+  ldflags = [ "-Wl,--no-as-needed" ]  # Force linking of all wasmer symbols.
+}
+
+rust_library("wasmer_lib") {
   lib_name = "wasmer"
-  shared = true
 }
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
index bc52ada..bfe6172 100644
--- a/third_party/wasmer/Cargo.toml
+++ b/third_party/wasmer/Cargo.toml
@@ -1,13 +1,11 @@
 [package]
 name = "wasmer"
-version = "1.0.0-alpha3"
+version = "0.17.1"
 
 [lib]
 name = "wasmer"
-crate-type = ["dylib"]
+crate-type = ["staticlib"]
 path = "wasmer.rs"
 
-[dependencies.wasmer-c-api]
-version = "1.0.0-alpha3"
-default-features = false
-features = ["jit", "cranelift", "wasi"]
+[dependencies]
+wasmer-runtime-c-api = "0.17.1"
diff --git a/third_party/wasmer/LICENSE b/third_party/wasmer/LICENSE
new file mode 100644
index 0000000..62bb543
--- /dev/null
+++ b/third_party/wasmer/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019-present Wasmer, Inc. and its affiliates.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/third_party/wasmer/README.google b/third_party/wasmer/README.google
new file mode 100644
index 0000000..aec1896
--- /dev/null
+++ b/third_party/wasmer/README.google
@@ -0,0 +1,11 @@
+Name: Wasmer Runtime C API
+Short Name: wasmer
+URL: https://github.com/wasmerio/wasmer/tree/master/lib/runtime-c-api
+Version: 0.6.0
+Date: August 16, 2019
+License: MIT
+
+Description:
+This directory contains an unmodified copy of wasmer.hh from the Wasmer Runtime
+C API (and README.md and LICENCE). Other files in this directory are added to
+build the corresponding rust library.
diff --git a/third_party/wasmer/README.md b/third_party/wasmer/README.md
new file mode 100644
index 0000000..d1475b7
--- /dev/null
+++ b/third_party/wasmer/README.md
@@ -0,0 +1,140 @@
+<p align="center">
+  <a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
+    <img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
+  </a>
+</p>
+
+<p align="center">
+  <a href="https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master">
+    <img src="https://img.shields.io/azure-devops/build/wasmerio/wasmer/3.svg?style=flat-square" alt="Build Status">
+  </a>
+  <a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE">
+    <img src="https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square" alt="License">
+  </a>
+  <a href="https://spectrum.chat/wasmer">
+    <img src="https://withspectrum.github.io/badge/badge.svg" alt="Join the Wasmer Community">
+  </a>
+  <a href="https://crates.io/crates/wasmer-runtime-c-api">
+    <img src="https://img.shields.io/crates/d/wasmer-runtime-c-api.svg?style=flat-square" alt="Number of downloads from crates.io">
+  </a>
+  <a href="https://wasmerio.github.io/wasmer/c/runtime-c-api/">
+    <img src="https://img.shields.io/badge/Docs-Wasmer%20C%20API-blue?style=flat-square" alt="Wasmer C API Documentation">
+  </a>
+</p>
+
+# Wasmer Runtime C API
+
+Wasmer is a standalone JIT WebAssembly runtime, aiming to be fully
+compatible with WASI, Emscripten, Rust and Go. [Learn
+more](https://github.com/wasmerio/wasmer).
+
+This crate exposes a C and a C++ API for the Wasmer runtime.
+
+# Usage
+
+The C and C++ header files can be found in the source tree of this
+crate, respectively [`wasmer.h`][wasmer_h] and
+[`wasmer.hh`][wasmer_hh]. They are automatically generated, and always
+up-to-date in this repository.
+The runtime shared library (so, dll, dylib) can also be downloaded in Wasmer [release page](https://github.com/wasmerio/wasmer/releases).
+
+You can find the full C API documentation here:
+https://wasmerio.github.io/wasmer/c/runtime-c-api/
+
+Here is a simple example to use the C API:
+
+```c
+#include <stdio.h>
+#include "../wasmer.h"
+#include <assert.h>
+#include <stdint.h>
+
+int main()
+{
+    // Read the Wasm file bytes.
+    FILE *file = fopen("sum.wasm", "r");
+    fseek(file, 0, SEEK_END);
+    long len = ftell(file);
+    uint8_t *bytes = malloc(len);
+    fseek(file, 0, SEEK_SET);
+    fread(bytes, 1, len, file);
+    fclose(file);
+
+    // Prepare the imports.
+    wasmer_import_t imports[] = {};
+
+    // Instantiate!
+    wasmer_instance_t *instance = NULL;
+    wasmer_result_t instantiation_result = wasmer_instantiate(&instance, bytes, len, imports, 0);
+
+    assert(instantiation_result == WASMER_OK);
+
+    // Let's call a function.
+    // Start by preparing the arguments.
+
+    // Value of argument #1 is `7i32`.
+    wasmer_value_t argument_one;
+    argument_one.tag = WASM_I32;
+    argument_one.value.I32 = 7;
+
+    // Value of argument #2 is `8i32`.
+    wasmer_value_t argument_two;
+    argument_two.tag = WASM_I32;
+    argument_two.value.I32 = 8;
+
+    // Prepare the arguments.
+    wasmer_value_t arguments[] = {argument_one, argument_two};
+
+    // Prepare the return value.
+    wasmer_value_t result_one;
+    wasmer_value_t results[] = {result_one};
+
+    // Call the `sum` function with the prepared arguments and the return value.
+    wasmer_result_t call_result = wasmer_instance_call(instance, "sum", arguments, 2, results, 1);
+
+    // Let's display the result.
+    printf("Call result:  %d\n", call_result);
+    printf("Result: %d\n", results[0].value.I32);
+
+    // `sum(7, 8) == 15`.
+    assert(results[0].value.I32 == 15);
+    assert(call_result == WASMER_OK);
+
+    wasmer_instance_destroy(instance);
+
+    return 0;
+}
+```
+
+# Testing
+
+Tests are run using the release build of the library.  If you make
+changes or compile with non-default features, please ensure you
+rebuild in release mode for the tests to see the changes.
+
+The tests can be run via `cargo test`, such as:
+
+```sh
+$ cargo test --release -- --nocapture
+```
+
+To run tests manually, enter the `lib/runtime-c-api/tests` directory
+and run the following commands:
+
+```sh
+$ cmake .
+$ make
+$ make test
+```
+
+
+# License
+
+Wasmer is primarily distributed under the terms of the [MIT
+license][mit-license] ([LICENSE][license]).
+
+
+[wasmer_h]: ./wasmer.h
+[wasmer_hh]: ./wasmer.hh
+[mit-license]: http://opensource.org/licenses/MIT
+[license]: https://github.com/wasmerio/wasmer/blob/master/LICENSE
diff --git a/third_party/wasmer/wasmer.hh b/third_party/wasmer/wasmer.hh
new file mode 100644
index 0000000..647e637
--- /dev/null
+++ b/third_party/wasmer/wasmer.hh
@@ -0,0 +1,1273 @@
+
+#if !defined(WASMER_H_MACROS)
+
+#define WASMER_H_MACROS
+
+// Define the `ARCH_X86_X64` constant.
+#if defined(MSVC) && defined(_M_AMD64)
+#  define ARCH_X86_64
+#elif (defined(GCC) || defined(__GNUC__) || defined(__clang__)) && defined(__x86_64__)
+#  define ARCH_X86_64
+#endif
+
+// Compatibility with non-Clang compilers.
+#if !defined(__has_attribute)
+#  define __has_attribute(x) 0
+#endif
+
+// Compatibility with non-Clang compilers.
+#if !defined(__has_declspec_attribute)
+#  define __has_declspec_attribute(x) 0
+#endif
+
+// Define the `DEPRECATED` macro.
+#if defined(GCC) || defined(__GNUC__) || __has_attribute(deprecated)
+#  define DEPRECATED(message) __attribute__((deprecated(message)))
+#elif defined(MSVC) || __has_declspec_attribute(deprecated)
+#  define DEPRECATED(message) __declspec(deprecated(message))
+#endif
+
+#define WASMER_WASI_ENABLED
+#endif // WASMER_H_MACROS
+
+
+#ifndef WASMER_H
+#define WASMER_H
+
+#include <cstdarg>
+#include <cstdint>
+#include <cstdlib>
+#include <new>
+
+#if defined(WASMER_WASI_ENABLED)
+enum class Version : uint8_t {
+  /// Version cannot be detected or is unknown.
+  Unknown = 0,
+  /// Latest version. See `wasmer_wasi::WasiVersion::Latest` to
+  /// learn more.
+  Latest = 1,
+  /// `wasi_unstable`.
+  Snapshot0 = 2,
+  /// `wasi_snapshot_preview1`.
+  Snapshot1 = 3,
+};
+#endif
+
+/// List of export/import kinds.
+enum class wasmer_import_export_kind : uint32_t {
+  /// The export/import is a function.
+  WASM_FUNCTION = 0,
+  /// The export/import is a global.
+  WASM_GLOBAL = 1,
+  /// The export/import is a memory.
+  WASM_MEMORY = 2,
+  /// The export/import is a table.
+  WASM_TABLE = 3,
+};
+
+/// The `wasmer_result_t` enum is a type that represents either a
+/// success, or a failure.
+enum class wasmer_result_t {
+  /// Represents a success.
+  WASMER_OK = 1,
+  /// Represents a failure.
+  WASMER_ERROR = 2,
+};
+
+/// Represents all possibles WebAssembly value types.
+///
+/// See `wasmer_value_t` to get a complete example.
+enum class wasmer_value_tag : uint32_t {
+  /// Represents the `i32` WebAssembly type.
+  WASM_I32,
+  /// Represents the `i64` WebAssembly type.
+  WASM_I64,
+  /// Represents the `f32` WebAssembly type.
+  WASM_F32,
+  /// Represents the `f64` WebAssembly type.
+  WASM_F64,
+};
+
+struct wasmer_module_t {
+
+};
+
+/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust.
+///
+/// A `wasmer_runtime::Instance` represents a WebAssembly instance. It
+/// is generally generated by the `wasmer_instantiate()` function, or by
+/// the `wasmer_module_instantiate()` function for the most common paths.
+struct wasmer_instance_t {
+
+};
+
+struct wasmer_byte_array {
+  const uint8_t *bytes;
+  uint32_t bytes_len;
+};
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Type used to construct an import_object_t with Emscripten imports.
+struct wasmer_emscripten_globals_t {
+
+};
+#endif
+
+struct wasmer_import_object_t {
+
+};
+
+/// Opaque pointer to `NamedExportDescriptor`.
+struct wasmer_export_descriptor_t {
+
+};
+
+/// Opaque pointer to `NamedExportDescriptors`.
+struct wasmer_export_descriptors_t {
+
+};
+
+/// Opaque pointer to `wasmer_export_t`.
+struct wasmer_export_func_t {
+
+};
+
+/// Represents a WebAssembly value.
+///
+/// This is a [Rust union][rust-union], which is equivalent to the C
+/// union. See `wasmer_value_t` to get a complete example.
+///
+/// [rust-union]: https://doc.rust-lang.org/reference/items/unions.html
+union wasmer_value {
+  int32_t I32;
+  int64_t I64;
+  float F32;
+  double F64;
+};
+
+/// Represents a WebAssembly type and value pair,
+/// i.e. `wasmer_value_tag` and `wasmer_value`. Since the latter is an
+/// union, it's the safe way to read or write a WebAssembly value in
+/// C.
+///
+/// Example:
+///
+/// ```c
+/// // Create a WebAssembly value.
+/// wasmer_value_t wasm_value = {
+///     .tag = WASM_I32,
+///     .value.I32 = 42,
+/// };
+///
+/// // Read a WebAssembly value.
+/// if (wasm_value.tag == WASM_I32) {
+///     int32_t x = wasm_value.value.I32;
+///     // …
+/// }
+/// ```
+struct wasmer_value_t {
+  /// The value type.
+  wasmer_value_tag tag;
+  /// The value.
+  wasmer_value value;
+};
+
+/// Opaque pointer to `NamedExport`.
+struct wasmer_export_t {
+
+};
+
+/// Opaque pointer to a `wasmer_runtime::Memory` value in Rust.
+///
+/// A `wasmer_runtime::Memory` represents a WebAssembly memory. It is
+/// possible to create one with `wasmer_memory_new()` and pass it as
+/// imports of an instance, or to read it from exports of an instance
+/// with `wasmer_export_to_memory()`.
+struct wasmer_memory_t {
+
+};
+
+/// Opaque pointer to the opaque structure `crate::NamedExports`,
+/// which is a wrapper around a vector of the opaque structure
+/// `crate::NamedExport`.
+///
+/// Check the `wasmer_instance_exports()` function to learn more.
+struct wasmer_exports_t {
+
+};
+
+struct wasmer_global_t {
+
+};
+
+struct wasmer_global_descriptor_t {
+  bool mutable_;
+  wasmer_value_tag kind;
+};
+
+struct wasmer_import_descriptor_t {
+
+};
+
+struct wasmer_import_descriptors_t {
+
+};
+
+struct wasmer_import_func_t {
+
+};
+
+struct wasmer_table_t {
+
+};
+
+/// Union of import/export value.
+union wasmer_import_export_value {
+  const wasmer_import_func_t *func;
+  const wasmer_table_t *table;
+  const wasmer_memory_t *memory;
+  const wasmer_global_t *global;
+};
+
+struct wasmer_import_t {
+  wasmer_byte_array module_name;
+  wasmer_byte_array import_name;
+  wasmer_import_export_kind tag;
+  wasmer_import_export_value value;
+};
+
+struct wasmer_import_object_iter_t {
+
+};
+
+/// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust.
+///
+/// An instance context is passed to any host function (aka imported
+/// function) as the first argument. It is necessary to read the
+/// instance data or the memory, respectively with the
+/// `wasmer_instance_context_data_get()` function, and the
+/// `wasmer_instance_context_memory()` function.
+///
+/// It is also possible to get the instance context outside a host
+/// function by using the `wasmer_instance_context_get()`
+/// function. See also `wasmer_instance_context_data_set()` to set the
+/// instance context data.
+///
+/// Example:
+///
+/// ```c
+/// // A host function that prints data from the WebAssembly memory to
+/// // the standard output.
+/// void print(wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
+///     // Use `wasmer_instance_context` to get back the first instance memory.
+///     const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
+///
+///     // Continue…
+/// }
+/// ```
+struct wasmer_instance_context_t {
+
+};
+
+/// The `wasmer_limit_option_t` struct represents an optional limit
+/// for `wasmer_limits_t`.
+struct wasmer_limit_option_t {
+  /// Whether the limit is set.
+  bool has_some;
+  /// The limit value.
+  uint32_t some;
+};
+
+/// The `wasmer_limits_t` struct is a type that describes a memory
+/// options. See the `wasmer_memory_t` struct or the
+/// `wasmer_memory_new()` function to get more information.
+struct wasmer_limits_t {
+  /// The minimum number of allowed pages.
+  uint32_t min;
+  /// The maximum number of allowed pages.
+  wasmer_limit_option_t max;
+};
+
+struct wasmer_serialized_module_t {
+
+};
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+struct wasmer_trampoline_buffer_builder_t {
+
+};
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+struct wasmer_trampoline_callable_t {
+
+};
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+struct wasmer_trampoline_buffer_t {
+
+};
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Opens a directory that's visible to the WASI module as `alias` but
+/// is backed by the host file at `host_file_path`
+struct wasmer_wasi_map_dir_entry_t {
+  /// What the WASI module will see in its virtual root
+  wasmer_byte_array alias;
+  /// The backing file that the WASI module will interact with via the alias
+  wasmer_byte_array host_file_path;
+};
+#endif
+
+extern "C" {
+
+/// Creates a new Module from the given wasm bytes.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_compile(wasmer_module_t **module,
+                               uint8_t *wasm_bytes,
+                               uint32_t wasm_bytes_len);
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Convenience function for setting up arguments and calling the Emscripten
+/// main function.
+///
+/// WARNING:
+///
+/// Do not call this function on untrusted code when operating without
+/// additional sandboxing in place.
+/// Emscripten has access to many host system calls and therefore may do very
+/// bad things.
+wasmer_result_t wasmer_emscripten_call_main(wasmer_instance_t *instance,
+                                            const wasmer_byte_array *args,
+                                            unsigned int args_len);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Destroy `wasmer_emscrpten_globals_t` created by
+/// `wasmer_emscripten_get_emscripten_globals`.
+void wasmer_emscripten_destroy_globals(wasmer_emscripten_globals_t *globals);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Create a `wasmer_import_object_t` with Emscripten imports, use
+/// `wasmer_emscripten_get_emscripten_globals` to get a
+/// `wasmer_emscripten_globals_t` from a `wasmer_module_t`.
+///
+/// WARNING:
+///
+/// This `import_object_t` contains thin-wrappers around host system calls.
+/// Do not use this to execute untrusted code without additional sandboxing.
+wasmer_import_object_t *wasmer_emscripten_generate_import_object(wasmer_emscripten_globals_t *globals);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Create a `wasmer_emscripten_globals_t` from a Wasm module.
+wasmer_emscripten_globals_t *wasmer_emscripten_get_globals(const wasmer_module_t *module);
+#endif
+
+#if defined(WASMER_EMSCRIPTEN_ENABLED)
+/// Execute global constructors (required if the module is compiled from C++)
+/// and sets up the internal environment.
+///
+/// This function sets the data pointer in the same way that
+/// [`wasmer_instance_context_data_set`] does.
+wasmer_result_t wasmer_emscripten_set_up(wasmer_instance_t *instance,
+                                         wasmer_emscripten_globals_t *globals);
+#endif
+
+/// Gets export descriptor kind
+wasmer_import_export_kind wasmer_export_descriptor_kind(wasmer_export_descriptor_t *export_);
+
+/// Gets name for the export descriptor
+wasmer_byte_array wasmer_export_descriptor_name(wasmer_export_descriptor_t *export_descriptor);
+
+/// Gets export descriptors for the given module
+///
+/// The caller owns the object and should call `wasmer_export_descriptors_destroy` to free it.
+void wasmer_export_descriptors(const wasmer_module_t *module,
+                               wasmer_export_descriptors_t **export_descriptors);
+
+/// Frees the memory for the given export descriptors
+void wasmer_export_descriptors_destroy(wasmer_export_descriptors_t *export_descriptors);
+
+/// Gets export descriptor by index
+wasmer_export_descriptor_t *wasmer_export_descriptors_get(wasmer_export_descriptors_t *export_descriptors,
+                                                          int idx);
+
+/// Gets the length of the export descriptors
+int wasmer_export_descriptors_len(wasmer_export_descriptors_t *exports);
+
+/// Calls a `func` with the provided parameters.
+/// Results are set using the provided `results` pointer.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_export_func_call(const wasmer_export_func_t *func,
+                                        const wasmer_value_t *params,
+                                        unsigned int params_len,
+                                        wasmer_value_t *results,
+                                        unsigned int results_len);
+
+/// Sets the params buffer to the parameter types of the given wasmer_export_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_export_func_params(const wasmer_export_func_t *func,
+                                          wasmer_value_tag *params,
+                                          uint32_t params_len);
+
+/// Sets the result parameter to the arity of the params of the wasmer_export_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_export_func_params_arity(const wasmer_export_func_t *func, uint32_t *result);
+
+/// Sets the returns buffer to the parameter types of the given wasmer_export_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_export_func_returns(const wasmer_export_func_t *func,
+                                           wasmer_value_tag *returns,
+                                           uint32_t returns_len);
+
+/// Sets the result parameter to the arity of the returns of the wasmer_export_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_export_func_returns_arity(const wasmer_export_func_t *func,
+                                                 uint32_t *result);
+
+/// Gets wasmer_export kind
+wasmer_import_export_kind wasmer_export_kind(wasmer_export_t *export_);
+
+/// Gets name from wasmer_export
+wasmer_byte_array wasmer_export_name(wasmer_export_t *export_);
+
+/// Gets export func from export
+const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_);
+
+/// Gets a memory pointer from an export pointer.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory);
+
+/// Frees the memory for the given exports.
+///
+/// Check the `wasmer_instance_exports()` function to get a complete
+/// example.
+///
+/// If `exports` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get some exports.
+/// wasmer_exports_t *exports = NULL;
+/// wasmer_instance_exports(instance, &exports);
+///
+/// // Destroy the exports.
+/// wasmer_exports_destroy(exports);
+/// ```
+void wasmer_exports_destroy(wasmer_exports_t *exports);
+
+/// Gets wasmer_export by index
+wasmer_export_t *wasmer_exports_get(wasmer_exports_t *exports, int idx);
+
+/// Gets the length of the exports
+int wasmer_exports_len(wasmer_exports_t *exports);
+
+/// Frees memory for the given Global
+void wasmer_global_destroy(wasmer_global_t *global);
+
+/// Gets the value stored by the given Global
+wasmer_value_t wasmer_global_get(wasmer_global_t *global);
+
+/// Returns a descriptor (type, mutability) of the given Global
+wasmer_global_descriptor_t wasmer_global_get_descriptor(wasmer_global_t *global);
+
+/// Creates a new Global and returns a pointer to it.
+/// The caller owns the object and should call `wasmer_global_destroy` to free it.
+wasmer_global_t *wasmer_global_new(wasmer_value_t value, bool mutable_);
+
+/// Sets the value stored by the given Global
+void wasmer_global_set(wasmer_global_t *global, wasmer_value_t value);
+
+/// Gets export descriptor kind
+wasmer_import_export_kind wasmer_import_descriptor_kind(wasmer_import_descriptor_t *export_);
+
+/// Gets module name for the import descriptor
+wasmer_byte_array wasmer_import_descriptor_module_name(wasmer_import_descriptor_t *import_descriptor);
+
+/// Gets name for the import descriptor
+wasmer_byte_array wasmer_import_descriptor_name(wasmer_import_descriptor_t *import_descriptor);
+
+/// Gets import descriptors for the given module
+///
+/// The caller owns the object and should call `wasmer_import_descriptors_destroy` to free it.
+void wasmer_import_descriptors(const wasmer_module_t *module,
+                               wasmer_import_descriptors_t **import_descriptors);
+
+/// Frees the memory for the given import descriptors
+void wasmer_import_descriptors_destroy(wasmer_import_descriptors_t *import_descriptors);
+
+/// Gets import descriptor by index
+wasmer_import_descriptor_t *wasmer_import_descriptors_get(wasmer_import_descriptors_t *import_descriptors,
+                                                          unsigned int idx);
+
+/// Gets the length of the import descriptors
+unsigned int wasmer_import_descriptors_len(wasmer_import_descriptors_t *exports);
+
+/// Frees memory for the given Func
+void wasmer_import_func_destroy(wasmer_import_func_t *func);
+
+/// Creates new host function, aka imported function. `func` is a
+/// function pointer, where the first argument is the famous `vm::Ctx`
+/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
+/// must be typed with compatible WebAssembly native types:
+///
+/// | WebAssembly type | C/C++ type |
+/// | ---------------- | ---------- |
+/// | `i32`            | `int32_t`  |
+/// | `i64`            | `int64_t`  |
+/// | `f32`            | `float`    |
+/// | `f64`            | `double`   |
+///
+/// The function pointer must have a lifetime greater than the
+/// WebAssembly instance lifetime.
+///
+/// The caller owns the object and should call
+/// `wasmer_import_func_destroy` to free it.
+wasmer_import_func_t *wasmer_import_func_new(void (*func)(void *data),
+                                             const wasmer_value_tag *params,
+                                             unsigned int params_len,
+                                             const wasmer_value_tag *returns,
+                                             unsigned int returns_len);
+
+/// Sets the params buffer to the parameter types of the given wasmer_import_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_import_func_params(const wasmer_import_func_t *func,
+                                          wasmer_value_tag *params,
+                                          unsigned int params_len);
+
+/// Sets the result parameter to the arity of the params of the wasmer_import_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_import_func_params_arity(const wasmer_import_func_t *func, uint32_t *result);
+
+/// Sets the returns buffer to the parameter types of the given wasmer_import_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_import_func_returns(const wasmer_import_func_t *func,
+                                           wasmer_value_tag *returns,
+                                           unsigned int returns_len);
+
+/// Sets the result parameter to the arity of the returns of the wasmer_import_func_t
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_import_func_returns_arity(const wasmer_import_func_t *func,
+                                                 uint32_t *result);
+
+/// Frees memory of the given ImportObject
+void wasmer_import_object_destroy(wasmer_import_object_t *import_object);
+
+/// Extends an existing import object with new imports
+wasmer_result_t wasmer_import_object_extend(wasmer_import_object_t *import_object,
+                                            const wasmer_import_t *imports,
+                                            unsigned int imports_len);
+
+/// Gets an entry from an ImportObject at the name and namespace.
+/// Stores `name`, `namespace`, and `import_export_value` in `import`.
+/// Thus these must remain valid for the lifetime of `import`.
+///
+/// The caller owns all data involved.
+/// `import_export_value` will be written to based on `tag`.
+wasmer_result_t wasmer_import_object_get_import(const wasmer_import_object_t *import_object,
+                                                wasmer_byte_array namespace_,
+                                                wasmer_byte_array name,
+                                                wasmer_import_t *import,
+                                                wasmer_import_export_value *import_export_value,
+                                                uint32_t tag);
+
+/// Frees the memory allocated in `wasmer_import_object_iter_next`
+///
+/// This function does not free the memory in `wasmer_import_object_t`;
+/// it only frees memory allocated while querying a `wasmer_import_object_t`.
+void wasmer_import_object_imports_destroy(wasmer_import_t *imports, uint32_t imports_len);
+
+/// Returns true if further calls to `wasmer_import_object_iter_next` will
+/// not return any new data
+bool wasmer_import_object_iter_at_end(wasmer_import_object_iter_t *import_object_iter);
+
+/// Frees the memory allocated by `wasmer_import_object_iterate_functions`
+void wasmer_import_object_iter_destroy(wasmer_import_object_iter_t *import_object_iter);
+
+/// Writes the next value to `import`.  `WASMER_ERROR` is returned if there
+/// was an error or there's nothing left to return.
+///
+/// To free the memory allocated here, pass the import to `wasmer_import_object_imports_destroy`.
+/// To check if the iterator is done, use `wasmer_import_object_iter_at_end`.
+wasmer_result_t wasmer_import_object_iter_next(wasmer_import_object_iter_t *import_object_iter,
+                                               wasmer_import_t *import);
+
+/// Create an iterator over the functions in the import object.
+/// Get the next import with `wasmer_import_object_iter_next`
+/// Free the iterator with `wasmer_import_object_iter_destroy`
+wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer_import_object_t *import_object);
+
+/// Creates a new empty import object.
+/// See also `wasmer_import_object_append`
+wasmer_import_object_t *wasmer_import_object_new();
+
+/// Calls an exported function of a WebAssembly instance by `name`
+/// with the provided parameters. The exported function results are
+/// stored on the provided `results` pointer.
+///
+/// This function returns `wasmer_result_t::WASMER_OK` upon success,
+/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use
+/// `wasmer_last_error_message()` to get the generated error message.
+///
+/// Potential errors are the following:
+///
+///   * `instance` is a null pointer,
+///   * `name` is a null pointer,
+///   * `params` is a null pointer.
+///
+/// Example of calling an exported function that needs two parameters, and returns one value:
+///
+/// ```c
+/// // First argument.
+/// wasmer_value_t argument_one = {
+///     .tag = WASM_I32,
+///     .value.I32 = 3,
+/// };
+///
+/// // Second argument.
+/// wasmer_value_t argument_two = {
+///     .tag = WASM_I32,
+///     .value.I32 = 4,
+/// };
+///
+/// // First result.
+/// wasmer_value_t result_one;
+///
+/// // All arguments and results.
+/// wasmer_value_t arguments[] = {argument_one, argument_two};
+/// wasmer_value_t results[]   = {result_one};
+///
+/// wasmer_result_t call_result = wasmer_instance_call(
+///     instance,  // instance pointer
+///     "sum",     // the exported function name
+///     arguments, // the arguments
+///     2,         // the number of arguments
+///     results,   // the results
+///     1          // the number of results
+/// );
+///
+/// if (call_result == WASMER_OK) {
+///     printf("Result is: %d\n", results[0].value.I32);
+/// }
+/// ```
+wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
+                                     const char *name,
+                                     const wasmer_value_t *params,
+                                     uint32_t params_len,
+                                     wasmer_value_t *results,
+                                     uint32_t results_len);
+
+/// Gets the data that can be hold by an instance.
+///
+/// This function is complementary of
+/// `wasmer_instance_context_data_set()`. Please read its
+/// documentation. You can also read the documentation of
+/// `wasmer_instance_context_t` to get other examples.
+///
+/// This function returns nothing if `ctx` is a null pointer.
+void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
+
+/// Sets the data that can be hold by an instance context.
+///
+/// An instance context (represented by the opaque
+/// `wasmer_instance_context_t` structure) can hold user-defined
+/// data. This function sets the data. This function is complementary
+/// of `wasmer_instance_context_data_get()`.
+///
+/// This function does nothing if `instance` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// // Define your own data.
+/// typedef struct {
+///     // …
+/// } my_data;
+///
+/// // Allocate them and set them on the given instance.
+/// my_data *data = malloc(sizeof(my_data));
+/// data->… = …;
+/// wasmer_instance_context_data_set(instance, (void*) data);
+///
+/// // You can read your data.
+/// {
+///     my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance));
+///     // …
+/// }
+/// ```
+void wasmer_instance_context_data_set(wasmer_instance_t *instance,
+                                      void *data_ptr);
+
+/// Returns the instance context. Learn more by looking at the
+/// `wasmer_instance_context_t` struct.
+///
+/// This function returns `null` if `instance` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance);
+/// my_data *data = (my_data *) wasmer_instance_context_data_get(context);
+/// // Do something with `my_data`.
+/// ```
+///
+/// It is often useful with `wasmer_instance_context_data_set()`.
+const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
+
+/// Gets the `memory_idx`th memory of the instance.
+///
+/// Note that the index is always `0` until multiple memories are supported.
+///
+/// This function is mostly used inside host functions (aka imported
+/// functions) to read the instance memory.
+///
+/// Example of a _host function_ that reads and prints a string based on a pointer and a length:
+///
+/// ```c
+/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
+///     // Get the 0th memory.
+///     const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
+///
+///     // Get the memory data as a pointer.
+///     uint8_t *memory_bytes = wasmer_memory_data(memory);
+///
+///     // Print what we assumed to be a string!
+///     printf("%.*s", length, memory_bytes + pointer);
+/// }
+/// ```
+const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
+                                                      uint32_t _memory_idx);
+
+/// Frees memory for the given `wasmer_instance_t`.
+///
+/// Check the `wasmer_instantiate()` function to get a complete
+/// example.
+///
+/// If `instance` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get an instance.
+/// wasmer_instance_t *instance = NULL;
+/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
+///
+/// // Destroy the instance.
+/// wasmer_instance_destroy(instance);
+/// ```
+void wasmer_instance_destroy(wasmer_instance_t *instance);
+
+/// Gets all the exports of the given WebAssembly instance.
+///
+/// This function stores a Rust vector of exports into `exports` as an
+/// opaque pointer of kind `wasmer_exports_t`.
+///
+/// As is, you can do anything with `exports` except using the
+/// companion functions, like `wasmer_exports_len()`,
+/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below.
+///
+/// **Warning**: The caller owns the object and should call
+/// `wasmer_exports_destroy()` to free it.
+///
+/// Example:
+///
+/// ```c
+/// // Get the exports.
+/// wasmer_exports_t *exports = NULL;
+/// wasmer_instance_exports(instance, &exports);
+///
+/// // Get the number of exports.
+/// int exports_length = wasmer_exports_len(exports);
+/// printf("Number of exports: %d\n", exports_length);
+///
+/// // Read the first export.
+/// wasmer_export_t *export = wasmer_exports_get(exports, 0);
+///
+/// // Get the kind of the export.
+/// wasmer_import_export_kind export_kind = wasmer_export_kind(export);
+///
+/// // Assert it is a function (why not).
+/// assert(export_kind == WASM_FUNCTION);
+///
+/// // Read the export name.
+/// wasmer_byte_array name_bytes = wasmer_export_name(export);
+///
+/// assert(name_bytes.bytes_len == sizeof("sum") - 1);
+/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0);
+///
+/// // Destroy the exports.
+/// wasmer_exports_destroy(exports);
+/// ```
+void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
+
+/// Creates a new WebAssembly instance from the given bytes and imports.
+///
+/// The result is stored in the first argument `instance` if
+/// successful, i.e. when the function returns
+/// `wasmer_result_t::WASMER_OK`. Otherwise
+/// `wasmer_result_t::WASMER_ERROR` is returned, and
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()` must
+/// be used to read the error message.
+///
+/// The caller is responsible to free the instance with
+/// `wasmer_instance_destroy()`.
+///
+/// Example:
+///
+/// ```c
+/// // 1. Read a WebAssembly module from a file.
+/// FILE *file = fopen("sum.wasm", "r");
+/// fseek(file, 0, SEEK_END);
+/// long bytes_length = ftell(file);
+/// uint8_t *bytes = malloc(bytes_length);
+/// fseek(file, 0, SEEK_SET);
+/// fread(bytes, 1, bytes_length, file);
+/// fclose(file);
+///
+/// // 2. Declare the imports (here, none).
+/// wasmer_import_t imports[] = {};
+///
+/// // 3. Instantiate the WebAssembly module.
+/// wasmer_instance_t *instance = NULL;
+/// wasmer_result_t result = wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
+///
+/// // 4. Check for errors.
+/// if (result != WASMER_OK) {
+///     int error_length = wasmer_last_error_length();
+///     char *error = malloc(error_length);
+///     wasmer_last_error_message(error, error_length);
+///     // Do something with `error`…
+/// }
+///
+/// // 5. Free the memory!
+/// wasmer_instance_destroy(instance);
+/// ```
+wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
+                                   uint8_t *wasm_bytes,
+                                   uint32_t wasm_bytes_len,
+                                   wasmer_import_t *imports,
+                                   int imports_len);
+
+/// Gets the length in bytes of the last error if any.
+///
+/// This can be used to dynamically allocate a buffer with the correct number of
+/// bytes needed to store a message.
+///
+/// See `wasmer_last_error_message()` to get a full example.
+int wasmer_last_error_length();
+
+/// Gets the last error message if any into the provided buffer
+/// `buffer` up to the given `length`.
+///
+/// The `length` parameter must be large enough to store the last
+/// error message. Ideally, the value should come from
+/// `wasmer_last_error_length()`.
+///
+/// The function returns the length of the string in bytes, `-1` if an
+/// error occurs. Potential errors are:
+///
+///  * The buffer is a null pointer,
+///  * The buffer is too smal to hold the error message.
+///
+/// Note: The error message always has a trailing null character.
+///
+/// Example:
+///
+/// ```c
+/// int error_length = wasmer_last_error_length();
+///
+/// if (error_length > 0) {
+///     char *error_message = malloc(error_length);
+///     wasmer_last_error_message(error_message, error_length);
+///     printf("Error message: `%s`\n", error_message);
+/// } else {
+///     printf("No error message\n");
+/// }
+/// ```
+int wasmer_last_error_message(char *buffer, int length);
+
+/// Gets a pointer to the beginning of the contiguous memory data
+/// bytes.
+///
+/// The function returns `NULL` if `memory` is a null pointer.
+///
+/// Note that when the memory grows, it can be reallocated, and thus
+/// the returned pointer can be invalidated.
+///
+/// Example:
+///
+/// ```c
+/// uint8_t *memory_data = wasmer_memory_data(memory);
+/// char *str = (char*) malloc(sizeof(char) * 7);
+///
+/// for (uint32_t nth = 0; nth < 7; ++nth) {
+///     str[nth] = (char) memory_data[nth];
+/// }
+/// ```
+uint8_t *wasmer_memory_data(const wasmer_memory_t *memory);
+
+/// Gets the size in bytes of the memory data.
+///
+/// This function returns 0 if `memory` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// uint32_t memory_data_length = wasmer_memory_data_length(memory);
+/// ```
+uint32_t wasmer_memory_data_length(const wasmer_memory_t *memory);
+
+/// Frees memory for the given `wasmer_memory_t`.
+///
+/// Check the `wasmer_memory_new()` function to get a complete
+/// example.
+///
+/// If `memory` is a null pointer, this function does nothing.
+///
+/// Example:
+///
+/// ```c
+/// // Get a memory.
+/// wasmer_memory_t *memory = NULL;
+/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
+///
+/// // Destroy the memory.
+/// wasmer_memory_destroy(memory);
+/// ```
+void wasmer_memory_destroy(wasmer_memory_t *memory);
+
+/// Grows a memory by the given number of pages (of 65Kb each).
+///
+/// The functions return `wasmer_result_t::WASMER_OK` upon success,
+/// `wasmer_result_t::WASMER_ERROR` otherwise. Use
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()` to
+/// read the error message.
+///
+/// Example:
+///
+/// ```c
+/// wasmer_result_t result = wasmer_memory_grow(memory, 10);
+///
+/// if (result != WASMER_OK) {
+///     // …
+/// }
+/// ```
+wasmer_result_t wasmer_memory_grow(wasmer_memory_t *memory, uint32_t delta);
+
+/// Reads the current length (in pages) of the given memory.
+///
+/// The function returns zero if `memory` is a null pointer.
+///
+/// Example:
+///
+/// ```c
+/// uint32_t memory_length = wasmer_memory_length(memory);
+///
+/// printf("Memory pages length: %d\n", memory_length);
+/// ```
+uint32_t wasmer_memory_length(const wasmer_memory_t *memory);
+
+/// Creates a new empty WebAssembly memory for the given descriptor.
+///
+/// The result is stored in the first argument `memory` if successful,
+/// i.e. when the function returns
+/// `wasmer_result_t::WASMER_OK`. Otherwise,
+/// `wasmer_result_t::WASMER_ERROR` is returned, and
+/// `wasmer_last_error_length()` with `wasmer_last_error_message()`
+/// must be used to read the error message.
+///
+/// The caller owns the memory and is responsible to free it with
+/// `wasmer_memory_destroy()`.
+///
+/// Example:
+///
+/// ```c
+/// // 1. The memory object.
+/// wasmer_memory_t *memory = NULL;
+///
+/// // 2. The memory descriptor.
+/// wasmer_limits_t memory_descriptor = {
+///     .min = 10,
+///     .max = {
+///         .has_some = true,
+///         .some = 15,
+///     },
+/// };
+///
+/// // 3. Initialize the memory.
+/// wasmer_result_t result = wasmer_memory_new(&memory, memory_descriptor);
+///
+/// if (result != WASMER_OK) {
+///     int error_length = wasmer_last_error_length();
+///     char *error = malloc(error_length);
+///     wasmer_last_error_message(error, error_length);
+///     // Do something with `error`…
+/// }
+///
+/// // 4. Free the memory!
+/// wasmer_memory_destroy(memory);
+/// ```
+wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits);
+
+/// Deserialize the given serialized module.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_module_deserialize(wasmer_module_t **module,
+                                          const wasmer_serialized_module_t *serialized_module);
+
+/// Frees memory for the given Module
+void wasmer_module_destroy(wasmer_module_t *module);
+
+/// Given:
+/// * A prepared `wasmer` import-object
+/// * A compiled wasmer module
+///
+/// Instantiates a wasmer instance
+wasmer_result_t wasmer_module_import_instantiate(wasmer_instance_t **instance,
+                                                 const wasmer_module_t *module,
+                                                 const wasmer_import_object_t *import_object);
+
+/// Creates a new Instance from the given module and imports.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_module_instantiate(const wasmer_module_t *module,
+                                          wasmer_instance_t **instance,
+                                          wasmer_import_t *imports,
+                                          int imports_len);
+
+/// Serialize the given Module.
+///
+/// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_module_serialize(wasmer_serialized_module_t **serialized_module,
+                                        const wasmer_module_t *module);
+
+/// Get bytes of the serialized module.
+wasmer_byte_array wasmer_serialized_module_bytes(const wasmer_serialized_module_t *serialized_module);
+
+/// Frees memory for the given serialized Module.
+void wasmer_serialized_module_destroy(wasmer_serialized_module_t *serialized_module);
+
+/// Transform a sequence of bytes into a serialized module.
+///
+/// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_serialized_module_from_bytes(wasmer_serialized_module_t **serialized_module,
+                                                    const uint8_t *serialized_module_bytes,
+                                                    uint32_t serialized_module_bytes_length);
+
+/// Frees memory for the given Table
+void wasmer_table_destroy(wasmer_table_t *table);
+
+/// Grows a Table by the given number of elements.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_table_grow(wasmer_table_t *table, uint32_t delta);
+
+/// Returns the current length of the given Table
+uint32_t wasmer_table_length(wasmer_table_t *table);
+
+/// Creates a new Table for the given descriptor and initializes the given
+/// pointer to pointer to a pointer to the new Table.
+///
+/// The caller owns the object and should call `wasmer_table_destroy` to free it.
+///
+/// Returns `wasmer_result_t::WASMER_OK` upon success.
+///
+/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
+/// and `wasmer_last_error_message` to get an error message.
+wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits);
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Adds a callinfo trampoline to the builder.
+///
+/// Deprecated. In a future version `DynamicFunc::new` will be exposed to the C API and should be used instead of this function.
+uintptr_t wasmer_trampoline_buffer_builder_add_callinfo_trampoline(wasmer_trampoline_buffer_builder_t *builder,
+                                                                   const wasmer_trampoline_callable_t *func,
+                                                                   const void *ctx,
+                                                                   uint32_t num_params);
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Adds a context trampoline to the builder.
+uintptr_t wasmer_trampoline_buffer_builder_add_context_trampoline(wasmer_trampoline_buffer_builder_t *builder,
+                                                                  const wasmer_trampoline_callable_t *func,
+                                                                  const void *ctx);
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Finalizes the trampoline builder into an executable buffer.
+wasmer_trampoline_buffer_t *wasmer_trampoline_buffer_builder_build(wasmer_trampoline_buffer_builder_t *builder);
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Creates a new trampoline builder.
+wasmer_trampoline_buffer_builder_t *wasmer_trampoline_buffer_builder_new();
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Destroys the trampoline buffer if not null.
+void wasmer_trampoline_buffer_destroy(wasmer_trampoline_buffer_t *buffer);
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Returns the callable pointer for the trampoline with index `idx`.
+const wasmer_trampoline_callable_t *wasmer_trampoline_buffer_get_trampoline(const wasmer_trampoline_buffer_t *buffer,
+                                                                            uintptr_t idx);
+#endif
+
+#if (!defined(_WIN32) && defined(ARCH_X86_64))
+/// Returns the context added by `add_context_trampoline`, from within the callee function.
+void *wasmer_trampoline_get_context();
+#endif
+
+/// Stop the execution of a host function, aka imported function. The
+/// function must be used _only_ inside a host function.
+///
+/// The pointer to `wasmer_instance_context_t` is received by the host
+/// function as its first argument. Just passing it to `ctx` is fine.
+///
+/// The error message must have a greater lifetime than the host
+/// function itself since the error is read outside the host function
+/// with `wasmer_last_error_message`.
+///
+/// This function returns `wasmer_result_t::WASMER_ERROR` if `ctx` or
+/// `error_message` are null.
+///
+/// This function never returns otherwise.
+wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message);
+
+/// Validates a sequence of bytes hoping it represents a valid WebAssembly module.
+///
+/// The function returns true if the bytes are valid, false otherwise.
+///
+/// Example:
+///
+/// ```c
+/// bool result = wasmer_validate(bytes, bytes_length);
+///
+/// if (false == result) {
+///     // Do something…
+/// }
+/// ```
+bool wasmer_validate(const uint8_t *wasm_bytes, uint32_t wasm_bytes_len);
+
+#if defined(WASMER_WASI_ENABLED)
+/// Convenience function that creates a WASI import object with no arguments,
+/// environment variables, preopened files, or mapped directories.
+///
+/// This function is the same as calling [`wasmer_wasi_generate_import_object`] with all
+/// empty values.
+wasmer_import_object_t *wasmer_wasi_generate_default_import_object();
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Creates a WASI import object.
+///
+/// This function treats null pointers as empty collections.
+/// For example, passing null for a string in `args`, will lead to a zero
+/// length argument in that position.
+wasmer_import_object_t *wasmer_wasi_generate_import_object(const wasmer_byte_array *args,
+                                                           unsigned int args_len,
+                                                           const wasmer_byte_array *envs,
+                                                           unsigned int envs_len,
+                                                           const wasmer_byte_array *preopened_files,
+                                                           unsigned int preopened_files_len,
+                                                           const wasmer_wasi_map_dir_entry_t *mapped_dirs,
+                                                           unsigned int mapped_dirs_len);
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Creates a WASI import object for a specific version.
+///
+/// This function is similar to `wasmer_wasi_generate_import_object`
+/// except that the first argument describes the WASI version.
+///
+/// The version is expected to be of kind `Version`.
+wasmer_import_object_t *wasmer_wasi_generate_import_object_for_version(unsigned char version,
+                                                                       const wasmer_byte_array *args,
+                                                                       unsigned int args_len,
+                                                                       const wasmer_byte_array *envs,
+                                                                       unsigned int envs_len,
+                                                                       const wasmer_byte_array *preopened_files,
+                                                                       unsigned int preopened_files_len,
+                                                                       const wasmer_wasi_map_dir_entry_t *mapped_dirs,
+                                                                       unsigned int mapped_dirs_len);
+#endif
+
+#if defined(WASMER_WASI_ENABLED)
+/// Find the version of WASI used by the module.
+///
+/// In case of error, the returned version is `Version::Unknown`.
+Version wasmer_wasi_get_version(const wasmer_module_t *module);
+#endif
+
+} // extern "C"
+
+#endif // WASMER_H
diff --git a/third_party/wasmer/wasmer.rs b/third_party/wasmer/wasmer.rs
index c4bd6e5..fdcb27a 100644
--- a/third_party/wasmer/wasmer.rs
+++ b/third_party/wasmer/wasmer.rs
@@ -1 +1 @@
-pub extern crate wasmer_c_api;
+pub extern crate wasmer_runtime_c_api;
diff --git a/third_party/wasmer/wasmer_wrapper.cc b/third_party/wasmer/wasmer_wrapper.cc
new file mode 100644
index 0000000..cdfaa69
--- /dev/null
+++ b/third_party/wasmer/wasmer_wrapper.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Wraps several functions from wasmer.hh, so that they take and return all
+// structs by pointer, rather than by value. This is necessary because Dart FFI
+// doesn't support passing structs by value yet (once it does, we can delete
+// this wrapper).
+
+#include "wasmer.hh"
+
+extern "C" {
+// Wraps wasmer_export_name.
+void wasmer_export_name_ptr(wasmer_export_t* export_,
+                            wasmer_byte_array* out_name) {
+  *out_name = wasmer_export_name(export_);
+}
+
+// Wraps wasmer_export_descriptor_name.
+void wasmer_export_descriptor_name_ptr(
+    wasmer_export_descriptor_t* export_descriptor,
+    wasmer_byte_array* out_name) {
+  *out_name = wasmer_export_descriptor_name(export_descriptor);
+}
+
+// Wraps wasmer_import_descriptor_module_name.
+void wasmer_import_descriptor_module_name_ptr(
+    wasmer_import_descriptor_t* import_descriptor,
+    wasmer_byte_array* out_name) {
+  *out_name = wasmer_import_descriptor_module_name(import_descriptor);
+}
+
+// Wraps wasmer_import_descriptor_name.
+void wasmer_import_descriptor_name_ptr(
+    wasmer_import_descriptor_t* import_descriptor,
+    wasmer_byte_array* out_name) {
+  *out_name = wasmer_import_descriptor_name(import_descriptor);
+}
+
+// Wraps wasmer_memory_new.
+wasmer_result_t wasmer_memory_new_ptr(wasmer_memory_t** memory,
+                                      wasmer_limits_t* limits) {
+  return wasmer_memory_new(memory, *limits);
+}
+}
diff --git a/tools/VERSION b/tools/VERSION
index ac56f0c..538e518 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 209
+PRERELEASE 210
 PRERELEASE_PATCH 0
\ No newline at end of file