diff --git a/DEPS b/DEPS
index 8aba9500501..3c59fe6c0c4 100644
--- a/DEPS
+++ b/DEPS
@@ -119,6 +119,7 @@ vars = {
"quiver-dart_tag": "2.0.0+1",
"resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
"root_certificates_rev": "16ef64be64c7dfdff2b9f4b910726e635ccc519e",
+ "rust_revision": "60960a260f7b5c695fd0717311d72ce62dd4eb43",
"shelf_static_rev": "v0.2.8",
"shelf_packages_handler_tag": "1.0.4",
"shelf_tag": "0.7.3+3",
@@ -434,6 +435,17 @@ deps = {
"dep_type": "cipd",
},
+ Var("dart_root") + "/buildtools/" + Var("host_os") + "-" + Var("host_cpu") + "/rust": {
+ "packages": [
+ {
+ "package": "fuchsia/rust/${{platform}}",
+ "version": "git_revision:" + Var("rust_revision"),
+ },
+ ],
+ "condition": "(host_os == 'linux' or host_os == 'mac') and host_cpu == 'x64'",
+ "dep_type": "cipd",
+ },
+
# TODO(37531): Remove these cipd packages and build with sdk instead when
# benchmark runner gets support for that.
Var("dart_root") + "/benchmarks/FfiBoringssl/dart/native/out/": {
diff --git a/build/rust/run.py b/build/rust/run.py
new file mode 100755
index 00000000000..6bdbea1273f
--- /dev/null
+++ b/build/rust/run.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Runs rust tools, overriding the PATH variable so they can locate each other.
+
+import os
+import subprocess
+import sys
+import time
+
+def run(cmd):
+ bindir = os.path.dirname(cmd[0]);
+ env = os.environ
+ if 'PATH' in env:
+ env['PATH'] += os.pathsep + bindir
+ else:
+ env['PATH'] = bindir
+ out = ''
+ err = ''
+ proc = subprocess.Popen(
+ cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ while proc.returncode is None:
+ time.sleep(1)
+ stdout, stderr = proc.communicate()
+ out += stdout
+ err += stderr
+ proc.poll()
+ if proc.returncode == 0:
+ return 0
+ print(out)
+ print(err)
+ return proc.returncode
+
+if __name__ == '__main__':
+ sys.exit(run(sys.argv[1:]))
diff --git a/build/rust/rust.gni b/build/rust/rust.gni
new file mode 100644
index 00000000000..6b4caf17a1c
--- /dev/null
+++ b/build/rust/rust.gni
@@ -0,0 +1,39 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+template("rust_library") {
+ manifest = rebase_path("Cargo.toml")
+ if (defined(invoker.manifest)) {
+ manifest = invoker.manifest
+ }
+
+ cmd = [
+ rebase_path("//buildtools/${current_os}-${current_cpu}/rust/bin/cargo"),
+ "build",
+ "--target-dir", rebase_path(target_out_dir),
+ "--manifest-path", manifest,
+ ]
+ output = "$target_out_dir/lib${invoker.lib_name}.a"
+ debug = defined(invoker.debug) && invoker.debug
+
+ if (!debug) {
+ cmd += [ "--release" ]
+ }
+
+ action(target_name) {
+ script = "//build/rust/run.py"
+ args = cmd
+ outputs = [ output ]
+ public_configs = [ ":${target_name}_config" ]
+ }
+
+ config("${target_name}_config") {
+ libs = [ "wasmer" ]
+ if (debug) {
+ lib_dirs = [ "$target_out_dir/debug" ]
+ } else {
+ lib_dirs = [ "$target_out_dir/release" ]
+ }
+ }
+}
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 28a6f8aa26b..0bd8a834a68 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -12,5 +12,6 @@
!clang.tar.gz.sha1
!unittest.tar.gz.sha1
!update.sh
+!/wasmer
# but ignore a subfolder of tcmalloc (some client ignores /tcmalloc/.gitignore)
/tcmalloc/gperftools
diff --git a/third_party/wasmer/.gitignore b/third_party/wasmer/.gitignore
new file mode 100644
index 00000000000..86a9394a250
--- /dev/null
+++ b/third_party/wasmer/.gitignore
@@ -0,0 +1,2 @@
+!*
+Cargo.lock
diff --git a/third_party/wasmer/BUILD.gn b/third_party/wasmer/BUILD.gn
new file mode 100644
index 00000000000..09093b6669d
--- /dev/null
+++ b/third_party/wasmer/BUILD.gn
@@ -0,0 +1,10 @@
+import("//build/rust/rust.gni")
+
+component("wasmer") {
+ public = [ "wasmer.hh" ]
+ deps = [ ":wasmer_lib" ]
+}
+
+rust_library("wasmer_lib") {
+ lib_name = "wasmer"
+}
diff --git a/third_party/wasmer/Cargo.toml b/third_party/wasmer/Cargo.toml
new file mode 100644
index 00000000000..62534303b1c
--- /dev/null
+++ b/third_party/wasmer/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "wasmer"
+version = "0.6.0"
+
+[lib]
+name = "wasmer"
+crate-type = ["staticlib"]
+path = "wasmer.rs"
+
+[dependencies]
+wasmer-runtime-c-api = "0.6.0"
diff --git a/third_party/wasmer/LICENSE b/third_party/wasmer/LICENSE
new file mode 100644
index 00000000000..079740dd377
--- /dev/null
+++ b/third_party/wasmer/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 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 00000000000..aec18966f3e
--- /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 00000000000..1e741cfd121
--- /dev/null
+++ b/third_party/wasmer/README.md
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Wasmer Runtime C API
+
+Wasmer is a standalone JIT WebAssembly runtime, aiming to be fully
+compatible with 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.
+
+Here is a simple example to use the C API:
+
+```c
+#include
+#include "../wasmer.h"
+#include
+#include
+
+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
+
+The tests can be run via `cargo test`, such as:
+
+```sh
+$ cargo test -- --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 00000000000..cf7a1c7b321
--- /dev/null
+++ b/third_party/wasmer/wasmer.hh
@@ -0,0 +1,532 @@
+#ifndef WASMER_H
+#define WASMER_H
+
+#include
+#include
+#include
+#include
+
+enum class wasmer_import_export_kind : uint32_t {
+ WASM_FUNCTION,
+ WASM_GLOBAL,
+ WASM_MEMORY,
+ WASM_TABLE,
+};
+
+enum class wasmer_result_t {
+ WASMER_OK = 1,
+ WASMER_ERROR = 2,
+};
+
+enum class wasmer_value_tag : uint32_t {
+ WASM_I32,
+ WASM_I64,
+ WASM_F32,
+ WASM_F64,
+};
+
+struct wasmer_module_t {
+
+};
+
+struct wasmer_export_descriptor_t {
+
+};
+
+struct wasmer_byte_array {
+ const uint8_t *bytes;
+ uint32_t bytes_len;
+};
+
+struct wasmer_export_descriptors_t {
+
+};
+
+struct wasmer_export_func_t {
+
+};
+
+union wasmer_value {
+ int32_t I32;
+ int64_t I64;
+ float F32;
+ double F64;
+};
+
+struct wasmer_value_t {
+ wasmer_value_tag tag;
+ wasmer_value value;
+};
+
+struct wasmer_export_t {
+
+};
+
+struct wasmer_memory_t {
+
+};
+
+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_import_object_t {
+
+};
+
+struct wasmer_table_t {
+
+};
+
+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_instance_t {
+
+};
+
+struct wasmer_instance_context_t {
+
+};
+
+struct wasmer_limit_option_t {
+ bool has_some;
+ uint32_t some;
+};
+
+struct wasmer_limits_t {
+ uint32_t min;
+ wasmer_limit_option_t max;
+};
+
+struct wasmer_serialized_module_t {
+
+};
+
+struct wasmer_trampoline_buffer_builder_t {
+
+};
+
+struct wasmer_trampoline_callable_t {
+
+};
+
+struct wasmer_trampoline_buffer_t {
+
+};
+
+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);
+
+/// 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,
+ int params_len,
+ wasmer_value_t *results,
+ 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
+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 func
+/// 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,
+ wasmer_import_t *imports,
+ unsigned int imports_len);
+
+/// Creates a new empty import object.
+/// See also `wasmer_import_object_append`
+wasmer_import_object_t *wasmer_import_object_new();
+
+/// Calls an instances exported function by `name` 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_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` field within the context.
+void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
+
+/// Sets the `data` field of the instance context. This context will be
+/// passed to all imported function for instance.
+void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr);
+
+/// Extracts the instance's context and returns it.
+const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
+
+/// Gets the memory within the context at the index `memory_idx`.
+/// The index is always 0 until multiple memories are supported.
+const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
+ uint32_t _memory_idx);
+
+/// Frees memory for the given Instance
+void wasmer_instance_destroy(wasmer_instance_t *instance);
+
+/// Gets Exports for the given instance
+/// The caller owns the object and should call `wasmer_exports_destroy` to free it.
+void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
+
+/// Creates a new Instance from the given wasm bytes 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_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.
+/// This can be used to dynamically allocate a buffer with the correct number of
+/// bytes needed to store a message.
+/// # Example
+/// ```c
+/// int error_len = wasmer_last_error_length();
+/// char *error_str = malloc(error_len);
+/// ```
+int wasmer_last_error_length();
+
+/// Stores the last error message into the provided buffer up to the given `length`.
+/// The `length` parameter must be large enough to store the last error message.
+/// Returns the length of the string in bytes.
+/// Returns `-1` if an error occurs.
+/// # Example
+/// ```c
+/// int error_len = wasmer_last_error_length();
+/// char *error_str = malloc(error_len);
+/// wasmer_last_error_message(error_str, error_len);
+/// printf("Error str: `%s`\n", error_str);
+/// ```
+int wasmer_last_error_message(char *buffer, int length);
+
+/// Gets the start pointer to the bytes within a Memory
+uint8_t *wasmer_memory_data(const wasmer_memory_t *mem);
+
+/// Gets the size in bytes of a Memory
+uint32_t wasmer_memory_data_length(wasmer_memory_t *mem);
+
+/// Frees memory for the given Memory
+void wasmer_memory_destroy(wasmer_memory_t *memory);
+
+/// Grows a Memory by the given number of pages.
+/// 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_memory_grow(wasmer_memory_t *memory, uint32_t delta);
+
+/// Returns the current length in pages of the given memory
+uint32_t wasmer_memory_length(const wasmer_memory_t *memory);
+
+/// Creates a new Memory for the given descriptor and initializes the given
+/// pointer to pointer to a pointer to the new memory.
+/// The caller owns the object and should call `wasmer_memory_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_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);
+
+/// Adds a callinfo trampoline to the builder.
+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);
+
+/// 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);
+
+/// Finalizes the trampoline builder into an executable buffer.
+wasmer_trampoline_buffer_t *wasmer_trampoline_buffer_builder_build(wasmer_trampoline_buffer_builder_t *builder);
+
+/// Creates a new trampoline builder.
+wasmer_trampoline_buffer_builder_t *wasmer_trampoline_buffer_builder_new();
+
+/// Destroys the trampoline buffer if not null.
+void wasmer_trampoline_buffer_destroy(wasmer_trampoline_buffer_t *buffer);
+
+/// 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);
+
+/// Returns the context added by `add_context_trampoline`, from within the callee function.
+void *wasmer_trampoline_get_context();
+
+/// Returns true for valid wasm bytes and false for invalid bytes
+bool wasmer_validate(const uint8_t *wasm_bytes, uint32_t wasm_bytes_len);
+
+} // extern "C"
+
+#endif // WASMER_H
diff --git a/third_party/wasmer/wasmer.rs b/third_party/wasmer/wasmer.rs
new file mode 100644
index 00000000000..fdcb27a1d5a
--- /dev/null
+++ b/third_party/wasmer/wasmer.rs
@@ -0,0 +1 @@
+pub extern crate wasmer_runtime_c_api;