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 logo + +

+ +

+ + Build Status + + + License + + + Join the Wasmer Community + + + Number of downloads from crates.io + + + Read our API documentation + +

+ +# 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;