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