wasmer/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 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 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 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 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 use inline_c::assert_c;
486
487 #[allow(
488 unexpected_cfgs,
489 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
490 )]
491 #[cfg_attr(coverage_nightly, coverage(off))]
492 #[test]
493 fn test_module_validate() {
494 (assert_c! {
495 #include "tests/wasmer.h"
496
497 int main() {
498 wasm_engine_t* engine = wasm_engine_new();
499 wasm_store_t* store = wasm_store_new(engine);
500
501 wasm_byte_vec_t wat;
502 wasmer_byte_vec_new_from_string(&wat, "(module)");
503 wasm_byte_vec_t wasm;
504 wat2wasm(&wat, &wasm);
505
506 assert(wasm_module_validate(store, &wasm));
507
508 wasm_byte_vec_delete(&wasm);
509 wasm_byte_vec_delete(&wat);
510 wasm_store_delete(store);
511 wasm_engine_delete(engine);
512
513 return 0;
514 }
515 })
516 .success();
517 }
518
519 #[allow(
520 unexpected_cfgs,
521 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
522 )]
523 #[cfg_attr(coverage_nightly, coverage(off))]
524 #[test]
525 fn test_module_new() {
526 (assert_c! {
527 #include "tests/wasmer.h"
528
529 int main() {
530 wasm_engine_t* engine = wasm_engine_new();
531 wasm_store_t* store = wasm_store_new(engine);
532
533 wasm_byte_vec_t wat;
534 wasmer_byte_vec_new_from_string(&wat, "(module)");
535 wasm_byte_vec_t wasm;
536 wat2wasm(&wat, &wasm);
537
538 wasm_module_t* module = wasm_module_new(store, &wasm);
539 assert(module);
540
541 wasm_byte_vec_delete(&wasm);
542 wasm_byte_vec_delete(&wat);
543 wasm_module_delete(module);
544 wasm_store_delete(store);
545 wasm_engine_delete(engine);
546
547 return 0;
548 }
549 })
550 .success();
551 }
552
553 #[allow(
554 unexpected_cfgs,
555 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
556 )]
557 #[cfg_attr(coverage_nightly, coverage(off))]
558 #[test]
559 fn test_module_exports() {
560 (assert_c! {
561 #include "tests/wasmer.h"
562
563 int main() {
564 wasm_engine_t* engine = wasm_engine_new();
565 wasm_store_t* store = wasm_store_new(engine);
566
567 wasm_byte_vec_t wat;
568 wasmer_byte_vec_new_from_string(
569 &wat,
570 "(module\n"
571 " (func (export \"function\") (param i32 i64))\n"
572 " (global (export \"global\") i32 (i32.const 7))\n"
573 " (table (export \"table\") 0 funcref)\n"
574 " (memory (export \"memory\") 1))"
575 );
576 wasm_byte_vec_t wasm;
577 wat2wasm(&wat, &wasm);
578
579 wasm_module_t* module = wasm_module_new(store, &wasm);
580 assert(module);
581
582 wasm_exporttype_vec_t export_types;
583 wasm_module_exports(module, &export_types);
584
585 assert(export_types.size == 4);
586
587 {
588 wasm_exporttype_t* export_type = export_types.data[0];
589
590 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
591 wasmer_assert_name(export_name, "function");
592
593 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
594 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_FUNC);
595
596 const wasm_functype_t* func_type = wasm_externtype_as_functype_const(extern_type);
597
598 const wasm_valtype_vec_t* func_params = wasm_functype_params(func_type);
599 assert(func_params && func_params->size == 2);
600 assert(wasm_valtype_kind(func_params->data[0]) == WASM_I32);
601 assert(wasm_valtype_kind(func_params->data[1]) == WASM_I64);
602
603 const wasm_valtype_vec_t* func_results = wasm_functype_results(func_type);
604 assert(func_results && func_results->size == 0);
605 }
606
607 {
608 wasm_exporttype_t* export_type = export_types.data[1];
609
610 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
611 wasmer_assert_name(export_name, "global");
612
613 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
614 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_GLOBAL);
615
616 const wasm_globaltype_t* global_type = wasm_externtype_as_globaltype_const(extern_type);
617 assert(wasm_valtype_kind(wasm_globaltype_content(global_type)) == WASM_I32);
618 assert(wasm_globaltype_mutability(global_type) == WASM_CONST);
619 }
620
621 {
622 wasm_exporttype_t* export_type = export_types.data[2];
623
624 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
625 wasmer_assert_name(export_name, "table");
626
627 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
628 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_TABLE);
629
630 const wasm_tabletype_t* table_type = wasm_externtype_as_tabletype_const(extern_type);
631 assert(wasm_valtype_kind(wasm_tabletype_element(table_type)) == WASM_FUNCREF);
632
633 const wasm_limits_t* table_limits = wasm_tabletype_limits(table_type);
634 assert(table_limits->min == 0);
635 assert(table_limits->max == wasm_limits_max_default);
636 }
637
638 {
639 wasm_exporttype_t* export_type = export_types.data[3];
640
641 const wasm_name_t* export_name = wasm_exporttype_name(export_type);
642 wasmer_assert_name(export_name, "memory");
643
644 const wasm_externtype_t* extern_type = wasm_exporttype_type(export_type);
645 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_MEMORY);
646
647 const wasm_memorytype_t* memory_type = wasm_externtype_as_memorytype_const(extern_type);
648 const wasm_limits_t* memory_limits = wasm_memorytype_limits(memory_type);
649 assert(memory_limits->min == 1);
650 assert(memory_limits->max == wasm_limits_max_default);
651 }
652
653 wasm_exporttype_vec_delete(&export_types);
654 wasm_byte_vec_delete(&wasm);
655 wasm_byte_vec_delete(&wat);
656 wasm_module_delete(module);
657 wasm_store_delete(store);
658 wasm_engine_delete(engine);
659
660 return 0;
661 }
662 })
663 .success();
664 }
665
666 #[allow(
667 unexpected_cfgs,
668 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
669 )]
670 #[cfg_attr(coverage_nightly, coverage(off))]
671 #[test]
672 fn test_module_imports() {
673 (assert_c! {
674 #include "tests/wasmer.h"
675
676 int main() {
677 wasm_engine_t* engine = wasm_engine_new();
678 wasm_store_t* store = wasm_store_new(engine);
679
680 wasm_byte_vec_t wat;
681 wasmer_byte_vec_new_from_string(
682 &wat,
683 "(module\n"
684 " (import \"ns\" \"function\" (func))\n"
685 " (import \"ns\" \"global\" (global f32))\n"
686 " (import \"ns\" \"table\" (table 1 2 funcref))\n"
687 " (import \"ns\" \"memory\" (memory 3 4)))"
688 );
689 wasm_byte_vec_t wasm;
690 wat2wasm(&wat, &wasm);
691
692 wasm_module_t* module = wasm_module_new(store, &wasm);
693 assert(module);
694
695 wasm_importtype_vec_t import_types;
696 wasm_module_imports(module, &import_types);
697
698 assert(import_types.size == 4);
699
700 {
701 const wasm_importtype_t* import_type = import_types.data[0];
702
703 const wasm_name_t* import_module = wasm_importtype_module(import_type);
704 wasmer_assert_name(import_module, "ns");
705
706 const wasm_name_t* import_name = wasm_importtype_name(import_type);
707 wasmer_assert_name(import_name, "function");
708
709 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
710 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_FUNC);
711
712 const wasm_functype_t* func_type = wasm_externtype_as_functype_const(extern_type);
713
714 const wasm_valtype_vec_t* func_params = wasm_functype_params(func_type);
715 assert(func_params && func_params->size == 0);
716
717 const wasm_valtype_vec_t* func_results = wasm_functype_results(func_type);
718 assert(func_results && func_results->size == 0);
719 }
720
721 {
722 const wasm_importtype_t* import_type = import_types.data[1];
723
724 const wasm_name_t* import_module = wasm_importtype_module(import_type);
725 wasmer_assert_name(import_module, "ns");
726
727 const wasm_name_t* import_name = wasm_importtype_name(import_type);
728 wasmer_assert_name(import_name, "global");
729
730 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
731 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_GLOBAL);
732
733 const wasm_globaltype_t* global_type = wasm_externtype_as_globaltype_const(extern_type);
734 assert(wasm_valtype_kind(wasm_globaltype_content(global_type)) == WASM_F32);
735 assert(wasm_globaltype_mutability(global_type) == WASM_CONST);
736 }
737
738 {
739 const wasm_importtype_t* import_type = import_types.data[2];
740
741 const wasm_name_t* import_module = wasm_importtype_module(import_type);
742 wasmer_assert_name(import_module, "ns");
743
744 const wasm_name_t* import_name = wasm_importtype_name(import_type);
745 wasmer_assert_name(import_name, "table");
746
747 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
748 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_TABLE);
749
750 const wasm_tabletype_t* table_type = wasm_externtype_as_tabletype_const(extern_type);
751 assert(wasm_valtype_kind(wasm_tabletype_element(table_type)) == WASM_FUNCREF);
752
753 const wasm_limits_t* table_limits = wasm_tabletype_limits(table_type);
754 assert(table_limits->min == 1);
755 assert(table_limits->max == 2);
756 }
757
758 {
759 const wasm_importtype_t* import_type = import_types.data[3];
760
761 const wasm_name_t* import_module = wasm_importtype_module(import_type);
762 wasmer_assert_name(import_module, "ns");
763
764 const wasm_name_t* import_name = wasm_importtype_name(import_type);
765 wasmer_assert_name(import_name, "memory");
766
767 const wasm_externtype_t* extern_type = wasm_importtype_type(import_type);
768 assert(wasm_externtype_kind(extern_type) == WASM_EXTERN_MEMORY);
769
770 const wasm_memorytype_t* memory_type = wasm_externtype_as_memorytype_const(extern_type);
771 const wasm_limits_t* memory_limits = wasm_memorytype_limits(memory_type);
772 assert(memory_limits->min == 3);
773 assert(memory_limits->max == 4);
774 }
775
776 wasm_importtype_vec_delete(&import_types);
777 wasm_module_delete(module);
778 wasm_byte_vec_delete(&wasm);
779 wasm_byte_vec_delete(&wat);
780 wasm_store_delete(store);
781 wasm_engine_delete(engine);
782
783 return 0;
784 }
785 })
786 .success();
787 }
788
789 #[allow(
790 unexpected_cfgs,
791 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
792 )]
793 #[cfg_attr(coverage_nightly, coverage(off))]
794 #[test]
795 fn test_module_serialize() {
796 (assert_c! {
797 #include "tests/wasmer.h"
798
799 int main() {
800 wasm_engine_t* engine = wasm_engine_new();
801 wasm_store_t* store = wasm_store_new(engine);
802
803 wasm_byte_vec_t wat;
804 wasmer_byte_vec_new_from_string(&wat, "(module)");
805 wasm_byte_vec_t wasm;
806 wat2wasm(&wat, &wasm);
807
808 wasm_module_t* module = wasm_module_new(store, &wasm);
809 assert(module);
810
811 wasm_byte_vec_t serialized_module;
812 wasm_module_serialize(module, &serialized_module);
813 assert(serialized_module.size > 0);
814
815 wasm_module_delete(module);
816 wasm_byte_vec_delete(&serialized_module);
817 wasm_byte_vec_delete(&wasm);
818 wasm_byte_vec_delete(&wat);
819 wasm_store_delete(store);
820 wasm_engine_delete(engine);
821
822 return 0;
823 }
824 })
825 .success();
826 }
827
828 #[allow(
829 unexpected_cfgs,
830 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
831 )]
832 #[cfg_attr(coverage_nightly, coverage(off))]
833 #[test]
834 fn test_module_serialize_and_deserialize() {
835 (assert_c! {
836 #include "tests/wasmer.h"
837
838 int main() {
839 wasm_engine_t* engine = wasm_engine_new();
840 wasm_store_t* store = wasm_store_new(engine);
841
842 wasm_byte_vec_t wat;
843 wasmer_byte_vec_new_from_string(
844 &wat,
845 "(module\n"
846 " (func (export \"function\") (param i32 i64))\n"
847 " (global (export \"global\") i32 (i32.const 7))\n"
848 " (table (export \"table\") 0 funcref)\n"
849 " (memory (export \"memory\") 1))"
850 );
851 wasm_byte_vec_t wasm;
852 wat2wasm(&wat, &wasm);
853
854 wasm_module_t* module = wasm_module_new(store, &wasm);
855 assert(module);
856
857 wasm_byte_vec_t serialized_module;
858 wasm_module_serialize(module, &serialized_module);
859 assert(serialized_module.size > 0);
860
861 wasm_module_delete(module);
862 wasm_module_t* deserialized_module = wasm_module_deserialize(
863 store,
864 &serialized_module
865 );
866 wasm_byte_vec_delete(&serialized_module);
867 assert(deserialized_module);
868
869 wasm_exporttype_vec_t export_types;
870 wasm_module_exports(deserialized_module, &export_types);
871
872 assert(export_types.size == 4);
873
874 wasm_exporttype_vec_delete(&export_types);
875 wasm_module_delete(deserialized_module);
876 wasm_byte_vec_delete(&wasm);
877 wasm_byte_vec_delete(&wat);
878 wasm_store_delete(store);
879 wasm_engine_delete(engine);
880
881 return 0;
882 }
883 })
884 .success();
885 }
886}