wasmer_c_api/wasm_c_api/unstable/
module.rs

1//! Unstable non-standard Wasmer-specific extensions to the Wasm C API.
2
3use super::super::engine::wasm_engine_t;
4use super::super::module::wasm_module_t;
5use super::super::types::{wasm_byte_vec_t, wasm_name_t};
6use std::ptr;
7use std::str;
8use wasmer_api::Module;
9
10/// Unstable non-standard Wasmer-specific API to get the module's
11/// name, otherwise `out->size` is set to `0` and `out->data` to
12/// `NULL`.
13///
14/// # Example
15///
16/// ```rust
17/// # use wasmer_inline_c::assert_c;
18/// # fn main() {
19/// #    (assert_c! {
20/// # #include "tests/wasmer.h"
21/// #
22/// int main() {
23///     // Create the engine and the store.
24///     wasm_engine_t* engine = wasm_engine_new();
25///     wasm_store_t* store = wasm_store_new(engine);
26///
27///     // Create a WebAssembly module from a WAT definition.
28///     wasm_byte_vec_t wat;
29///     wasmer_byte_vec_new_from_string(&wat, "(module $moduleName)");
30///     //                                             ^~~~~~~~~~~ that's the name!
31///     wasm_byte_vec_t wasm;
32///     wat2wasm(&wat, &wasm);
33///
34///     // Create the module.
35///     wasm_module_t* module = wasm_module_new(store, &wasm);
36///
37///     // Read the module's name.
38///     wasm_name_t name;
39///     wasmer_module_name(module, &name);
40///
41///     // It works!
42///     wasmer_assert_name(&name, "moduleName");
43///
44///     // Free everything.
45///     wasm_byte_vec_delete(&name);
46///     wasm_module_delete(module);
47///     wasm_byte_vec_delete(&wasm);
48///     wasm_byte_vec_delete(&wat);
49///     wasm_store_delete(store);
50///     wasm_engine_delete(engine);
51///
52///     return 0;
53/// }
54/// #    })
55/// #    .success();
56/// # }
57/// ```
58#[unsafe(no_mangle)]
59pub unsafe extern "C" fn wasmer_module_name(
60    module: &wasm_module_t,
61    // own
62    out: &mut wasm_name_t,
63) {
64    let name = match module.inner.name() {
65        Some(name) => name,
66        None => {
67            out.data = ptr::null_mut();
68            out.size = 0;
69
70            return;
71        }
72    };
73
74    out.set_buffer(name.as_bytes().to_vec());
75}
76
77/// Unstable non-standard Wasmer-specific API to set the module's
78/// name. The function returns `true` if the name has been updated,
79/// `false` otherwise.
80///
81/// # Example
82///
83/// ```rust
84/// # use wasmer_inline_c::assert_c;
85/// # fn main() {
86/// #    (assert_c! {
87/// # #include "tests/wasmer.h"
88/// #
89/// int main() {
90///     // Create the engine and the store.
91///     wasm_engine_t* engine = wasm_engine_new();
92///     wasm_store_t* store = wasm_store_new(engine);
93///
94///     // Create a WebAssembly module from a WAT definition.
95///     wasm_byte_vec_t wat;
96///     wasmer_byte_vec_new_from_string(&wat, "(module)");
97///     wasm_byte_vec_t wasm;
98///     wat2wasm(&wat, &wasm);
99///
100///     // Create the module.
101///     wasm_module_t* module = wasm_module_new(store, &wasm);
102///
103///     // Read the module's name. There is none for the moment.
104///     {
105///         wasm_name_t name;
106///         wasmer_module_name(module, &name);
107///
108///         assert(name.size == 0);
109///     }
110///
111///     // So, let's set a new name.
112///     {
113///         wasm_name_t name;
114///         wasmer_byte_vec_new_from_string(&name, "hello");
115///         wasmer_module_set_name(module, &name);
116///     }
117///
118///     // And now, let's see the new name.
119///     {
120///         wasm_name_t name;
121///         wasmer_module_name(module, &name);
122///
123///         // It works!
124///         wasmer_assert_name(&name, "hello");
125///
126///         wasm_byte_vec_delete(&name);
127///     }
128///
129///     // Free everything.
130///     wasm_module_delete(module);
131///     wasm_byte_vec_delete(&wasm);
132///     wasm_byte_vec_delete(&wat);
133///     wasm_store_delete(store);
134///     wasm_engine_delete(engine);
135///
136///     return 0;
137/// }
138/// #    })
139/// #    .success();
140/// # }
141/// ```
142#[unsafe(no_mangle)]
143pub unsafe extern "C" fn wasmer_module_set_name(
144    module: &mut wasm_module_t,
145    // own
146    name: &wasm_name_t,
147) -> bool {
148    let name = match str::from_utf8(name.as_slice()) {
149        Ok(name) => name,
150        Err(_) => return false, // not ideal!
151    };
152
153    module.inner.set_name(name)
154}
155
156/// A WebAssembly module contains stateless WebAssembly code that has
157/// already been compiled and can be instantiated multiple times.
158///
159/// Creates a new WebAssembly Module using the provided engine,
160/// respecting its configuration.
161///
162/// ## Security
163///
164/// Before the code is compiled, it will be validated using the engine
165/// features.
166///
167/// # Example
168///
169/// See the module's documentation.
170#[unsafe(no_mangle)]
171pub unsafe extern "C" fn wasmer_module_new(
172    engine: Option<&mut wasm_engine_t>,
173    bytes: Option<&wasm_byte_vec_t>,
174) -> Option<Box<wasm_module_t>> {
175    let engine: wasmer_api::Engine = engine?.inner.clone();
176    let bytes = bytes?;
177
178    let module = c_try!(Module::from_binary(&engine, bytes.as_slice()));
179
180    Some(Box::new(wasm_module_t { inner: module }))
181}