wasmer_c_api/wasm_c_api/module.rs
1use super::store::wasm_store_t;
2use super::types::{wasm_byte_vec_t, wasm_exporttype_vec_t, wasm_importtype_vec_t};
3use std::ptr::NonNull;
4use wasmer_api::Module;
5
6/// Opaque type representing a WebAssembly module.
7#[derive(Clone)]
8#[allow(non_camel_case_types)]
9pub struct wasm_module_t {
10 pub(crate) inner: Module,
11}
12
13/// A WebAssembly module contains stateless WebAssembly code that has
14/// already been compiled and can be instantiated multiple times.
15///
16/// Creates a new WebAssembly Module given the configuration
17/// in the store.
18///
19/// ## Security
20///
21/// Before the code is compiled, it will be validated using the store
22/// features.
23///
24/// # Example
25///
26/// See the module's documentation.
27#[unsafe(no_mangle)]
28pub unsafe extern "C" fn wasm_module_new(
29 store: Option<&mut wasm_store_t>,
30 bytes: Option<&wasm_byte_vec_t>,
31) -> Option<Box<wasm_module_t>> {
32 let store = store?;
33 let store_mut = unsafe { store.inner.store_mut() };
34 let bytes = bytes?;
35
36 let module = c_try!(Module::from_binary(&store_mut, bytes.as_slice()));
37
38 Some(Box::new(wasm_module_t { inner: module }))
39}
40
41/// Deletes a WebAssembly module.
42///
43/// # Example
44///
45/// See [`wasm_module_new`].
46#[unsafe(no_mangle)]
47pub unsafe extern "C" fn wasm_module_delete(_module: Option<Box<wasm_module_t>>) {}
48
49/// Validates a new WebAssembly module given the configuration
50/// in the [store][super::store].
51///
52/// This validation is normally pretty fast and checks the enabled
53/// WebAssembly features in the [store engine][super::engine] to
54/// assure deterministic validation of the module.
55///
56/// # Example
57///
58/// ```rust
59/// # use wasmer_inline_c::assert_c;
60/// # fn main() {
61/// # (assert_c! {
62/// # #include "tests/wasmer.h"
63/// #
64/// int main() {
65/// // Create the engine and the store.
66/// wasm_engine_t* engine = wasm_engine_new();
67/// wasm_store_t* store = wasm_store_new(engine);
68///
69/// // Create a WebAssembly module from a WAT definition.
70/// wasm_byte_vec_t wat;
71/// wasmer_byte_vec_new_from_string(&wat, "(module)");
72/// wasm_byte_vec_t wasm;
73/// wat2wasm(&wat, &wasm);
74///
75/// // Validate that the WebAssembly module is correct.
76/// assert(wasm_module_validate(store, &wasm));
77///
78/// // Free everything.
79/// wasm_byte_vec_delete(&wasm);
80/// wasm_byte_vec_delete(&wat);
81/// wasm_store_delete(store);
82/// wasm_engine_delete(engine);
83///
84/// return 0;
85/// }
86/// # })
87/// # .success();
88/// # }
89/// ```
90#[unsafe(no_mangle)]
91pub unsafe extern "C" fn wasm_module_validate(
92 store: Option<&mut wasm_store_t>,
93 bytes: Option<&wasm_byte_vec_t>,
94) -> bool {
95 let store = match store {
96 Some(store) => unsafe { store.inner.store_mut() },
97 None => return false,
98 };
99 let bytes = match bytes {
100 Some(bytes) => bytes,
101 None => return false,
102 };
103
104 Module::validate(&store, bytes.as_slice())
105 .map(|_| true)
106 .unwrap_or(false)
107}
108
109/// Returns an array of the exported types in the module.
110///
111/// The order of the exports is guaranteed to be the same as in the
112/// WebAssembly bytecode.
113///
114/// # Example
115///
116/// ```rust
117/// # use wasmer_inline_c::assert_c;
118/// # fn main() {
119/// # (assert_c! {
120/// # #include "tests/wasmer.h"
121/// #
122/// int main() {
123/// // Create the engine and the store.
124/// wasm_engine_t* engine = wasm_engine_new();
125/// wasm_store_t* store = wasm_store_new(engine);
126///
127/// // Create a WebAssembly module from a WAT definition.
128/// wasm_byte_vec_t wat;
129/// wasmer_byte_vec_new_from_string(
130/// &wat,
131/// "(module\n"
132/// " (func (export \"function\") (param i32 i64))\n"
133/// " (global (export \"global\") i32 (i32.const 7))\n"
134/// " (table (export \"table\") 0 funcref)\n"
135/// " (memory (export \"memory\") 1))"
136/// );
137/// wasm_byte_vec_t wasm;
138/// wat2wasm(&wat, &wasm);
139///
140/// // Create the module.
141/// wasm_module_t* module = wasm_module_new(store, &wasm);
142/// assert(module);
143///
144/// // Extract the types exported by this module.
145/// wasm_exporttype_vec_t export_types;
146/// wasm_module_exports(module, &export_types);
147///
148/// // We have 4 of them.
149/// assert(export_types.size == 4);
150///
151/// // The first one is a function. Use
152/// // `wasm_externtype_as_functype_const` to continue to inspect the
153/// // type.
154/// {
155/// wasm_exporttype_t* export_type = export_types.data[0];
156///
157/// const wasm_name_t* export_name = wasm_exporttype_name(export_type);
158/// wasmer_assert_name(export_name, "function");
159///
160/// const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
161/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_FUNC);
162/// }
163///
164/// // The second one is a global. Use
165/// // `wasm_externtype_as_globaltype_const` to continue to inspect the
166/// // type.
167/// {
168/// wasm_exporttype_t* export_type = export_types.data[1];
169///
170/// const wasm_name_t* export_name = wasm_exporttype_name(export_type);
171/// wasmer_assert_name(export_name, "global");
172///
173/// const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
174/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_GLOBAL);
175/// }
176///
177/// // The third one is a table. Use
178/// // `wasm_externtype_as_tabletype_const` to continue to inspect the
179/// // type.
180/// {
181/// wasm_exporttype_t* export_type = export_types.data[2];
182///
183/// const wasm_name_t* export_name = wasm_exporttype_name(export_type);
184/// wasmer_assert_name(export_name, "table");
185///
186/// const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
187/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_TABLE);
188/// }
189///
190/// // The fourth one is a memory. Use
191/// // `wasm_externtype_as_memorytype_const` to continue to inspect the
192/// // type.
193/// {
194/// wasm_exporttype_t* export_type = export_types.data[3];
195///
196/// const wasm_name_t* export_name = wasm_exporttype_name(export_type);
197/// wasmer_assert_name(export_name, "memory");
198///
199/// const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
200/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_MEMORY);
201/// }
202///
203/// // Free everything.
204/// wasm_exporttype_vec_delete(&export_types);
205/// wasm_byte_vec_delete(&wasm);
206/// wasm_byte_vec_delete(&wat);
207/// wasm_module_delete(module);
208/// wasm_store_delete(store);
209/// wasm_engine_delete(engine);
210///
211/// return 0;
212/// }
213/// # })
214/// # .success();
215/// # }
216/// ```
217#[unsafe(no_mangle)]
218pub unsafe extern "C" fn wasm_module_exports(
219 module: &wasm_module_t,
220 // own
221 out: &mut wasm_exporttype_vec_t,
222) {
223 let exports = module
224 .inner
225 .exports()
226 .map(|export| Some(Box::new(export.into())))
227 .collect();
228
229 out.set_buffer(exports);
230}
231
232/// Returns an array of the imported types in the module.
233///
234/// The order of the imports is guaranteed to be the same as in the
235/// WebAssembly bytecode.
236///
237/// # Example
238///
239/// ```rust
240/// # use wasmer_inline_c::assert_c;
241/// # fn main() {
242/// # (assert_c! {
243/// # #include "tests/wasmer.h"
244/// #
245/// int main() {
246/// // Create the engine and the store.
247/// wasm_engine_t* engine = wasm_engine_new();
248/// wasm_store_t* store = wasm_store_new(engine);
249///
250/// // Create a WebAssembly module from a WAT definition.
251/// wasm_byte_vec_t wat;
252/// wasmer_byte_vec_new_from_string(
253/// &wat,
254/// "(module\n"
255/// " (import \"ns\" \"function\" (func))\n"
256/// " (import \"ns\" \"global\" (global f32))\n"
257/// " (import \"ns\" \"table\" (table 1 2 funcref))\n"
258/// " (import \"ns\" \"memory\" (memory 3 4)))"
259/// );
260/// wasm_byte_vec_t wasm;
261/// wat2wasm(&wat, &wasm);
262///
263/// // Create the module.
264/// wasm_module_t* module = wasm_module_new(store, &wasm);
265/// assert(module);
266///
267/// // Extract the types imported by the module.
268/// wasm_importtype_vec_t import_types;
269/// wasm_module_imports(module, &import_types);
270///
271/// // We have 4 of them.
272/// assert(import_types.size == 4);
273///
274/// // The first one is a function. Use
275/// // `wasm_externtype_as_functype_const` to continue to inspect the
276/// // type.
277/// {
278/// const wasm_importtype_t* import_type = import_types.data[0];
279///
280/// const wasm_name_t* import_module = wasm_importtype_module(import_type);
281/// wasmer_assert_name(import_module, "ns");
282///
283/// const wasm_name_t* import_name = wasm_importtype_name(import_type);
284/// wasmer_assert_name(import_name, "function");
285///
286/// const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
287/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_FUNC);
288/// }
289///
290/// // The second one is a global. Use
291/// // `wasm_externtype_as_globaltype_const` to continue to inspect
292/// // the type.
293/// {
294/// const wasm_importtype_t* import_type = import_types.data[1];
295///
296/// const wasm_name_t* import_module = wasm_importtype_module(import_type);
297/// wasmer_assert_name(import_module, "ns");
298///
299/// const wasm_name_t* import_name = wasm_importtype_name(import_type);
300/// wasmer_assert_name(import_name, "global");
301///
302/// const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
303/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_GLOBAL);
304/// }
305///
306/// // The third one is a table. Use
307/// // `wasm_externtype_as_tabletype_const` to continue to inspect
308/// // the type.
309/// {
310/// const wasm_importtype_t* import_type = import_types.data[2];
311///
312/// const wasm_name_t* import_module = wasm_importtype_module(import_type);
313/// wasmer_assert_name(import_module, "ns");
314///
315/// const wasm_name_t* import_name = wasm_importtype_name(import_type);
316/// wasmer_assert_name(import_name, "table");
317///
318/// const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
319/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_TABLE);
320/// }
321///
322/// // The fourth one is a memory. Use
323/// // `wasm_externtype_as_memorytype_const` to continue to inspect
324/// // the type.
325/// {
326/// const wasm_importtype_t* import_type = import_types.data[3];
327///
328/// const wasm_name_t* import_module = wasm_importtype_module(import_type);
329/// wasmer_assert_name(import_module, "ns");
330///
331/// const wasm_name_t* import_name = wasm_importtype_name(import_type);
332/// wasmer_assert_name(import_name, "memory");
333///
334/// const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
335/// assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_MEMORY);
336///
337/// const wasm_memorytype_t* memory_type = wasm_externtype_as_memorytype_const(extern_type);
338/// const wasm_limits_t* memory_limits = wasm_memorytype_limits(memory_type);
339/// assert(memory_limits->min == 3);
340/// assert(memory_limits->max == 4);
341/// }
342///
343/// // Free everything.
344/// wasm_importtype_vec_delete(&import_types);
345/// wasm_module_delete(module);
346/// wasm_byte_vec_delete(&wasm);
347/// wasm_byte_vec_delete(&wat);
348/// wasm_store_delete(store);
349/// wasm_engine_delete(engine);
350///
351/// return 0;
352/// }
353/// # })
354/// # .success();
355/// # }
356/// ```
357#[unsafe(no_mangle)]
358pub unsafe extern "C" fn wasm_module_imports(
359 module: &wasm_module_t,
360 // own
361 out: &mut wasm_importtype_vec_t,
362) {
363 let imports = module
364 .inner
365 .imports()
366 .map(|import| Some(Box::new(import.into())))
367 .collect();
368
369 out.set_buffer(imports);
370}
371
372/// Deserializes a serialized module binary into a `wasm_module_t`.
373///
374/// Note: the module has to be serialized before with the
375/// `wasm_module_serialize` function.
376///
377/// # Safety
378///
379/// This function is inherently **unsafe** as the provided bytes:
380///
381/// 1. Are going to be deserialized directly into Rust and C objects,
382/// 2. Contains the function assembly bodies and, if intercepted,
383/// a malicious actor could inject code into executable
384/// memory.
385///
386/// And as such, the `wasm_module_deserialize` method is unsafe.
387///
388/// # Example
389///
390/// ```rust
391/// # use wasmer_inline_c::assert_c;
392/// # fn main() {
393/// # (assert_c! {
394/// # #include "tests/wasmer.h"
395/// #
396/// int main() {
397/// // Create the engine and the store.
398/// wasm_engine_t* engine = wasm_engine_new();
399/// wasm_store_t* store = wasm_store_new(engine);
400///
401/// // Create a WebAssembly module from a WAT definition.
402/// wasm_byte_vec_t wat;
403/// wasmer_byte_vec_new_from_string(
404/// &wat,
405/// "(module\n"
406/// " (func (export \"function\") (param i32 i64))\n"
407/// " (global (export \"global\") i32 (i32.const 7))\n"
408/// " (table (export \"table\") 0 funcref)\n"
409/// " (memory (export \"memory\") 1))"
410/// );
411/// wasm_byte_vec_t wasm;
412/// wat2wasm(&wat, &wasm);
413///
414/// // Create the module.
415/// wasm_module_t* module = wasm_module_new(store, &wasm);
416/// assert(module);
417///
418/// // Serialize the module into bytes.
419/// wasm_byte_vec_t serialized_module;
420/// wasm_module_serialize(module, &serialized_module);
421/// assert(serialized_module.size > 0);
422///
423/// // Free the module.
424/// wasm_module_delete(module);
425///
426/// // Deserialize the serialized module. Note that the store must
427/// // be the same as the one used to serialize.
428/// wasm_module_t* deserialized_module = wasm_module_deserialize(
429/// store,
430/// &serialized_module
431/// );
432/// wasm_byte_vec_delete(&serialized_module);
433/// assert(deserialized_module);
434///
435/// // Check we have our 4 export types.
436/// wasm_exporttype_vec_t export_types;
437/// wasm_module_exports(deserialized_module, &export_types);
438///
439/// assert(export_types.size == 4);
440///
441/// // Free everything.
442/// wasm_exporttype_vec_delete(&export_types);
443/// wasm_module_delete(deserialized_module);
444/// wasm_byte_vec_delete(&wasm);
445/// wasm_byte_vec_delete(&wat);
446/// wasm_store_delete(store);
447/// wasm_engine_delete(engine);
448///
449/// return 0;
450/// }
451/// # })
452/// # .success();
453/// # }
454/// ```
455#[unsafe(no_mangle)]
456pub unsafe extern "C" fn wasm_module_deserialize(
457 store: &wasm_store_t,
458 bytes: Option<&wasm_byte_vec_t>,
459) -> Option<NonNull<wasm_module_t>> {
460 let bytes = bytes?;
461
462 let store_ref = unsafe { store.inner.store() };
463 let module = c_try!(unsafe { Module::deserialize(&store_ref, bytes.as_slice()) });
464
465 Some(unsafe {
466 NonNull::new_unchecked(Box::into_raw(Box::new(wasm_module_t { inner: module })))
467 })
468}
469
470/// Serializes a module into a binary representation that the
471/// [engine][super::engine] can later process via
472/// [`wasm_module_deserialize`].
473///
474/// # Example
475///
476/// See [`wasm_module_deserialize`].
477#[unsafe(no_mangle)]
478pub unsafe extern "C" fn wasm_module_serialize(module: &wasm_module_t, out: &mut wasm_byte_vec_t) {
479 let byte_vec = c_try!(module.inner.serialize(); otherwise ());
480 out.set_buffer(byte_vec.to_vec());
481}
482
483#[cfg(test)]
484mod tests {
485 #[cfg(not(target_os = "windows"))]
486 use inline_c::assert_c;
487 #[cfg(target_os = "windows")]
488 use wasmer_inline_c::assert_c;
489
490 #[allow(
491 unexpected_cfgs,
492 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
493 )]
494 #[cfg_attr(coverage, ignore)]
495 #[test]
496 fn test_module_validate() {
497 (assert_c! {
498 #include "tests/wasmer.h"
499
500 int main() {
501 wasm_engine_t* engine = wasm_engine_new();
502 wasm_store_t* store = wasm_store_new(engine);
503
504 wasm_byte_vec_t wat;
505 wasmer_byte_vec_new_from_string(&wat, "(module)");
506 wasm_byte_vec_t wasm;
507 wat2wasm(&wat, &wasm);
508
509 assert(wasm_module_validate(store, &wasm));
510
511 wasm_byte_vec_delete(&wasm);
512 wasm_byte_vec_delete(&wat);
513 wasm_store_delete(store);
514 wasm_engine_delete(engine);
515
516 return 0;
517 }
518 })
519 .success();
520 }
521
522 #[allow(
523 unexpected_cfgs,
524 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
525 )]
526 #[cfg_attr(coverage, ignore)]
527 #[test]
528 fn test_module_new() {
529 (assert_c! {
530 #include "tests/wasmer.h"
531
532 int main() {
533 wasm_engine_t* engine = wasm_engine_new();
534 wasm_store_t* store = wasm_store_new(engine);
535
536 wasm_byte_vec_t wat;
537 wasmer_byte_vec_new_from_string(&wat, "(module)");
538 wasm_byte_vec_t wasm;
539 wat2wasm(&wat, &wasm);
540
541 wasm_module_t* module = wasm_module_new(store, &wasm);
542 assert(module);
543
544 wasm_byte_vec_delete(&wasm);
545 wasm_byte_vec_delete(&wat);
546 wasm_module_delete(module);
547 wasm_store_delete(store);
548 wasm_engine_delete(engine);
549
550 return 0;
551 }
552 })
553 .success();
554 }
555
556 #[allow(
557 unexpected_cfgs,
558 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
559 )]
560 #[cfg_attr(coverage, ignore)]
561 #[test]
562 fn test_module_exports() {
563 (assert_c! {
564 #include "tests/wasmer.h"
565
566 int main() {
567 wasm_engine_t* engine = wasm_engine_new();
568 wasm_store_t* store = wasm_store_new(engine);
569
570 wasm_byte_vec_t wat;
571 wasmer_byte_vec_new_from_string(
572 &wat,
573 "(module\n"
574 " (func (export \"function\") (param i32 i64))\n"
575 " (global (export \"global\") i32 (i32.const 7))\n"
576 " (table (export \"table\") 0 funcref)\n"
577 " (memory (export \"memory\") 1))"
578 );
579 wasm_byte_vec_t wasm;
580 wat2wasm(&wat, &wasm);
581
582 wasm_module_t* module = wasm_module_new(store, &wasm);
583 assert(module);
584
585 wasm_exporttype_vec_t export_types;
586 wasm_module_exports(module, &export_types);
587
588 assert(export_types.size == 4);
589
590 {
591 wasm_exporttype_t* export_type = export_types.data[0];
592
593 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
594 wasmer_assert_name(export_name, "function");
595
596 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
597 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_FUNC);
598
599 const wasm_functype_t* func_type = wasm_externtype_as_functype_const(extern_type);
600
601 const wasm_valtype_vec_t* func_params = wasm_functype_params(func_type);
602 assert(func_params && func_params->size == 2);
603 assert(wasm_valtype_kind(func_params->data[0]) == WASM_I32);
604 assert(wasm_valtype_kind(func_params->data[1]) == WASM_I64);
605
606 const wasm_valtype_vec_t* func_results = wasm_functype_results(func_type);
607 assert(func_results && func_results->size == 0);
608 }
609
610 {
611 wasm_exporttype_t* export_type = export_types.data[1];
612
613 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
614 wasmer_assert_name(export_name, "global");
615
616 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
617 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_GLOBAL);
618
619 const wasm_globaltype_t* global_type = wasm_externtype_as_globaltype_const(extern_type);
620 assert(wasm_valtype_kind(wasm_globaltype_content(global_type)) == WASM_I32);
621 assert(wasm_globaltype_mutability(global_type) == WASM_CONST);
622 }
623
624 {
625 wasm_exporttype_t* export_type = export_types.data[2];
626
627 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
628 wasmer_assert_name(export_name, "table");
629
630 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
631 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_TABLE);
632
633 const wasm_tabletype_t* table_type = wasm_externtype_as_tabletype_const(extern_type);
634 assert(wasm_valtype_kind(wasm_tabletype_element(table_type)) == WASM_FUNCREF);
635
636 const wasm_limits_t* table_limits = wasm_tabletype_limits(table_type);
637 assert(table_limits->min == 0);
638 assert(table_limits->max == wasm_limits_max_default);
639 }
640
641 {
642 wasm_exporttype_t* export_type = export_types.data[3];
643
644 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
645 wasmer_assert_name(export_name, "memory");
646
647 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
648 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_MEMORY);
649
650 const wasm_memorytype_t* memory_type = wasm_externtype_as_memorytype_const(extern_type);
651 const wasm_limits_t* memory_limits = wasm_memorytype_limits(memory_type);
652 assert(memory_limits->min == 1);
653 assert(memory_limits->max == wasm_limits_max_default);
654 }
655
656 wasm_exporttype_vec_delete(&export_types);
657 wasm_byte_vec_delete(&wasm);
658 wasm_byte_vec_delete(&wat);
659 wasm_module_delete(module);
660 wasm_store_delete(store);
661 wasm_engine_delete(engine);
662
663 return 0;
664 }
665 })
666 .success();
667 }
668
669 #[allow(
670 unexpected_cfgs,
671 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
672 )]
673 #[cfg_attr(coverage, ignore)]
674 #[test]
675 fn test_module_imports() {
676 (assert_c! {
677 #include "tests/wasmer.h"
678
679 int main() {
680 wasm_engine_t* engine = wasm_engine_new();
681 wasm_store_t* store = wasm_store_new(engine);
682
683 wasm_byte_vec_t wat;
684 wasmer_byte_vec_new_from_string(
685 &wat,
686 "(module\n"
687 " (import \"ns\" \"function\" (func))\n"
688 " (import \"ns\" \"global\" (global f32))\n"
689 " (import \"ns\" \"table\" (table 1 2 funcref))\n"
690 " (import \"ns\" \"memory\" (memory 3 4)))"
691 );
692 wasm_byte_vec_t wasm;
693 wat2wasm(&wat, &wasm);
694
695 wasm_module_t* module = wasm_module_new(store, &wasm);
696 assert(module);
697
698 wasm_importtype_vec_t import_types;
699 wasm_module_imports(module, &import_types);
700
701 assert(import_types.size == 4);
702
703 {
704 const wasm_importtype_t* import_type = import_types.data[0];
705
706 const wasm_name_t* import_module = wasm_importtype_module(import_type);
707 wasmer_assert_name(import_module, "ns");
708
709 const wasm_name_t* import_name = wasm_importtype_name(import_type);
710 wasmer_assert_name(import_name, "function");
711
712 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
713 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_FUNC);
714
715 const wasm_functype_t* func_type = wasm_externtype_as_functype_const(extern_type);
716
717 const wasm_valtype_vec_t* func_params = wasm_functype_params(func_type);
718 assert(func_params && func_params->size == 0);
719
720 const wasm_valtype_vec_t* func_results = wasm_functype_results(func_type);
721 assert(func_results && func_results->size == 0);
722 }
723
724 {
725 const wasm_importtype_t* import_type = import_types.data[1];
726
727 const wasm_name_t* import_module = wasm_importtype_module(import_type);
728 wasmer_assert_name(import_module, "ns");
729
730 const wasm_name_t* import_name = wasm_importtype_name(import_type);
731 wasmer_assert_name(import_name, "global");
732
733 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
734 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_GLOBAL);
735
736 const wasm_globaltype_t* global_type = wasm_externtype_as_globaltype_const(extern_type);
737 assert(wasm_valtype_kind(wasm_globaltype_content(global_type)) == WASM_F32);
738 assert(wasm_globaltype_mutability(global_type) == WASM_CONST);
739 }
740
741 {
742 const wasm_importtype_t* import_type = import_types.data[2];
743
744 const wasm_name_t* import_module = wasm_importtype_module(import_type);
745 wasmer_assert_name(import_module, "ns");
746
747 const wasm_name_t* import_name = wasm_importtype_name(import_type);
748 wasmer_assert_name(import_name, "table");
749
750 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
751 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_TABLE);
752
753 const wasm_tabletype_t* table_type = wasm_externtype_as_tabletype_const(extern_type);
754 assert(wasm_valtype_kind(wasm_tabletype_element(table_type)) == WASM_FUNCREF);
755
756 const wasm_limits_t* table_limits = wasm_tabletype_limits(table_type);
757 assert(table_limits->min == 1);
758 assert(table_limits->max == 2);
759 }
760
761 {
762 const wasm_importtype_t* import_type = import_types.data[3];
763
764 const wasm_name_t* import_module = wasm_importtype_module(import_type);
765 wasmer_assert_name(import_module, "ns");
766
767 const wasm_name_t* import_name = wasm_importtype_name(import_type);
768 wasmer_assert_name(import_name, "memory");
769
770 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
771 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_MEMORY);
772
773 const wasm_memorytype_t* memory_type = wasm_externtype_as_memorytype_const(extern_type);
774 const wasm_limits_t* memory_limits = wasm_memorytype_limits(memory_type);
775 assert(memory_limits->min == 3);
776 assert(memory_limits->max == 4);
777 }
778
779 wasm_importtype_vec_delete(&import_types);
780 wasm_module_delete(module);
781 wasm_byte_vec_delete(&wasm);
782 wasm_byte_vec_delete(&wat);
783 wasm_store_delete(store);
784 wasm_engine_delete(engine);
785
786 return 0;
787 }
788 })
789 .success();
790 }
791
792 #[allow(
793 unexpected_cfgs,
794 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
795 )]
796 #[cfg_attr(coverage, ignore)]
797 #[test]
798 fn test_module_serialize() {
799 (assert_c! {
800 #include "tests/wasmer.h"
801
802 int main() {
803 wasm_engine_t* engine = wasm_engine_new();
804 wasm_store_t* store = wasm_store_new(engine);
805
806 wasm_byte_vec_t wat;
807 wasmer_byte_vec_new_from_string(&wat, "(module)");
808 wasm_byte_vec_t wasm;
809 wat2wasm(&wat, &wasm);
810
811 wasm_module_t* module = wasm_module_new(store, &wasm);
812 assert(module);
813
814 wasm_byte_vec_t serialized_module;
815 wasm_module_serialize(module, &serialized_module);
816 assert(serialized_module.size > 0);
817
818 wasm_module_delete(module);
819 wasm_byte_vec_delete(&serialized_module);
820 wasm_byte_vec_delete(&wasm);
821 wasm_byte_vec_delete(&wat);
822 wasm_store_delete(store);
823 wasm_engine_delete(engine);
824
825 return 0;
826 }
827 })
828 .success();
829 }
830
831 #[allow(
832 unexpected_cfgs,
833 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
834 )]
835 #[cfg_attr(coverage, ignore)]
836 #[test]
837 fn test_module_serialize_and_deserialize() {
838 (assert_c! {
839 #include "tests/wasmer.h"
840
841 int main() {
842 wasm_engine_t* engine = wasm_engine_new();
843 wasm_store_t* store = wasm_store_new(engine);
844
845 wasm_byte_vec_t wat;
846 wasmer_byte_vec_new_from_string(
847 &wat,
848 "(module\n"
849 " (func (export \"function\") (param i32 i64))\n"
850 " (global (export \"global\") i32 (i32.const 7))\n"
851 " (table (export \"table\") 0 funcref)\n"
852 " (memory (export \"memory\") 1))"
853 );
854 wasm_byte_vec_t wasm;
855 wat2wasm(&wat, &wasm);
856
857 wasm_module_t* module = wasm_module_new(store, &wasm);
858 assert(module);
859
860 wasm_byte_vec_t serialized_module;
861 wasm_module_serialize(module, &serialized_module);
862 assert(serialized_module.size > 0);
863
864 wasm_module_delete(module);
865 wasm_module_t* deserialized_module = wasm_module_deserialize(
866 store,
867 &serialized_module
868 );
869 wasm_byte_vec_delete(&serialized_module);
870 assert(deserialized_module);
871
872 wasm_exporttype_vec_t export_types;
873 wasm_module_exports(deserialized_module, &export_types);
874
875 assert(export_types.size == 4);
876
877 wasm_exporttype_vec_delete(&export_types);
878 wasm_module_delete(deserialized_module);
879 wasm_byte_vec_delete(&wasm);
880 wasm_byte_vec_delete(&wat);
881 wasm_store_delete(store);
882 wasm_engine_delete(engine);
883
884 return 0;
885 }
886 })
887 .success();
888 }
889}