1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
#![doc(html_favicon_url = "https://wasmer.io/static/icons/favicon.ico")] #![doc(html_logo_url = "https://avatars3.githubusercontent.com/u/44205449?s=200&v=4")] //! # 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 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 <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; //! } //! ``` //! //! [wasmer_h]: ./wasmer.h //! [wasmer_hh]: ./wasmer.hh #![deny( dead_code, unused_imports, unused_variables, unused_unsafe, unreachable_patterns )] extern crate wasmer_runtime; extern crate wasmer_runtime_core; pub mod error; pub mod export; pub mod global; pub mod import; pub mod instance; pub mod memory; pub mod module; pub mod table; // `not(target_family = "windows")` is simpler than `unix`. See build.rs // if you want to change the meaning of these `cfg`s in the header file. #[cfg(all(not(target_family = "windows"), target_arch = "x86_64"))] pub mod trampoline; pub mod value; /// The `wasmer_result_t` enum is a type that represents either a /// success, or a failure. #[allow(non_camel_case_types)] #[repr(C)] pub enum wasmer_result_t { /// Represents a success. WASMER_OK = 1, /// Represents a failure. WASMER_ERROR = 2, } /// 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. #[repr(C)] pub struct wasmer_limits_t { /// The minimum number of allowed pages. pub min: u32, /// The maximum number of allowed pages. pub max: wasmer_limit_option_t, } /// The `wasmer_limit_option_t` struct represents an optional limit /// for `wasmer_limits_t`. #[repr(C)] pub struct wasmer_limit_option_t { /// Whether the limit is set. pub has_some: bool, /// The limit value. pub some: u32, } #[repr(C)] pub struct wasmer_byte_array { pub bytes: *const u8, pub bytes_len: u32, } impl wasmer_byte_array { /// Get the data as a slice pub unsafe fn as_slice<'a>(&self) -> &'a [u8] { get_slice_checked(self.bytes, self.bytes_len as usize) } /// Copy the data into an owned Vec pub unsafe fn as_vec(&self) -> Vec<u8> { let mut out = Vec::with_capacity(self.bytes_len as usize); out.extend_from_slice(self.as_slice()); out } /// Read the data as a &str, returns an error if the string is not valid UTF8 pub unsafe fn as_str<'a>(&self) -> Result<&'a str, std::str::Utf8Error> { std::str::from_utf8(self.as_slice()) } } /// Gets a slice from a pointer and a length, returning an empty slice if the /// pointer is null #[inline] pub(crate) unsafe fn get_slice_checked<'a, T>(ptr: *const T, len: usize) -> &'a [T] { if ptr.is_null() { &[] } else { std::slice::from_raw_parts(ptr, len) } }