1use super::ffi;
4use crate::{types::WasmEdgeLimit, WasmEdgeResult};
5use std::{borrow::Cow, ffi::CStr};
6use wasmedge_types::{
7 error::{ExportError, ImportError, WasmEdgeError},
8 ExternalInstanceType, FuncType, GlobalType, MemoryType, Mutability, RefType, TableType,
9 ValType,
10};
11
12#[derive(Debug)]
19pub struct Module {
20 pub(crate) inner: InnerModule,
21}
22impl Drop for Module {
23 fn drop(&mut self) {
24 unsafe { ffi::WasmEdge_ASTModuleDelete(self.inner.0) };
25 }
26}
27impl Module {
28 pub fn count_of_imports(&self) -> u32 {
30 unsafe { ffi::WasmEdge_ASTModuleListImportsLength(self.inner.0) }
31 }
32
33 pub fn imports(&self) -> Vec<ImportType<'_>> {
35 let size = self.count_of_imports();
36 let mut returns = Vec::with_capacity(size as usize);
37 unsafe {
38 ffi::WasmEdge_ASTModuleListImports(self.inner.0, returns.as_mut_ptr(), size);
39 returns.set_len(size as usize);
40 }
41
42 returns
43 .into_iter()
44 .map(|ctx| ImportType {
45 inner: InnerImportType(ctx),
46 module: self,
47 })
48 .collect()
49 }
50
51 pub fn count_of_exports(&self) -> u32 {
53 unsafe { ffi::WasmEdge_ASTModuleListExportsLength(self.inner.0) }
54 }
55
56 pub fn export(&self) -> Vec<ExportType<'_>> {
58 let size = self.count_of_exports();
59 let mut returns = Vec::with_capacity(size as usize);
60 unsafe {
61 ffi::WasmEdge_ASTModuleListExports(self.inner.0, returns.as_mut_ptr(), size);
62 returns.set_len(size as usize);
63 }
64
65 returns
66 .into_iter()
67 .map(|ctx| ExportType {
68 inner: InnerExportType(ctx),
69 module: self,
70 })
71 .collect()
72 }
73
74 pub unsafe fn from_raw(ptr: *mut ffi::WasmEdge_ASTModuleContext) -> Self {
75 Self {
76 inner: InnerModule(ptr),
77 }
78 }
79}
80
81#[derive(Debug, Clone, Copy)]
82pub(crate) struct InnerModule(pub(crate) *mut ffi::WasmEdge_ASTModuleContext);
83unsafe impl Send for InnerModule {}
84unsafe impl Sync for InnerModule {}
85
86#[derive(Debug)]
88pub struct ImportType<'module> {
89 pub(crate) inner: InnerImportType,
90 pub(crate) module: &'module Module,
91}
92impl Drop for ImportType<'_> {
93 fn drop(&mut self) {
94 if !self.inner.0.is_null() {
95 self.inner.0 = std::ptr::null();
96 }
97 }
98}
99impl ImportType<'_> {
100 pub fn ty(&self) -> WasmEdgeResult<ExternalInstanceType> {
102 let ty = unsafe { ffi::WasmEdge_ImportTypeGetExternalType(self.inner.0) };
103 let ty: ExternalInstanceType = ty.into();
104 match ty {
105 ExternalInstanceType::Func(_) => {
106 let ctx_func_ty = unsafe {
107 ffi::WasmEdge_ImportTypeGetFunctionType(
108 self.module.inner.0 as *const _,
109 self.inner.0 as *const _,
110 )
111 };
112 match ctx_func_ty.is_null() {
113 true => Err(Box::new(WasmEdgeError::Import(ImportError::FuncType(
114 "Fail to get the function type".into(),
115 )))),
116 false => {
117 let args_len = unsafe {
119 ffi::WasmEdge_FunctionTypeGetParametersLength(ctx_func_ty) as usize
120 };
121 let mut args = Vec::with_capacity(args_len);
122 unsafe {
123 ffi::WasmEdge_FunctionTypeGetParameters(
124 ctx_func_ty,
125 args.as_mut_ptr(),
126 args_len as u32,
127 );
128 args.set_len(args_len);
129 }
130 let args: Vec<ValType> = args.into_iter().map(Into::into).collect();
131
132 let returns_len = unsafe {
134 ffi::WasmEdge_FunctionTypeGetReturnsLength(ctx_func_ty) as usize
135 };
136 let mut returns = Vec::with_capacity(returns_len);
137 unsafe {
138 ffi::WasmEdge_FunctionTypeGetReturns(
139 ctx_func_ty,
140 returns.as_mut_ptr(),
141 returns_len as u32,
142 );
143 returns.set_len(returns_len);
144 }
145 let returns: Vec<ValType> = returns.into_iter().map(Into::into).collect();
146
147 Ok(ExternalInstanceType::Func(FuncType::new(args, returns)))
148 }
149 }
150 }
151 ExternalInstanceType::Global(_) => {
152 let ctx_global_ty = unsafe {
153 ffi::WasmEdge_ImportTypeGetGlobalType(self.module.inner.0, self.inner.0)
154 };
155 match ctx_global_ty.is_null() {
156 true => Err(Box::new(WasmEdgeError::Import(ImportError::MemType(
157 "Fail to get the global type".into(),
158 )))),
159 false => {
160 let val = unsafe { ffi::WasmEdge_GlobalTypeGetValType(ctx_global_ty) };
162 let val_ty: ValType = val.into();
163
164 let val = unsafe { ffi::WasmEdge_GlobalTypeGetMutability(ctx_global_ty) };
166 let mutability: Mutability = val.into();
167
168 Ok(ExternalInstanceType::Global(GlobalType::new(
169 val_ty, mutability,
170 )))
171 }
172 }
173 }
174 ExternalInstanceType::Memory(_) => {
175 let ctx_mem_ty = unsafe {
176 ffi::WasmEdge_ImportTypeGetMemoryType(self.module.inner.0, self.inner.0)
177 };
178 match ctx_mem_ty.is_null() {
179 true => Err(Box::new(WasmEdgeError::Import(ImportError::MemType(
180 "Fail to get the memory type".into(),
181 )))),
182 false => {
183 let limit = unsafe { ffi::WasmEdge_MemoryTypeGetLimit(ctx_mem_ty) };
184 let limit = WasmEdgeLimit::from_context(limit);
185
186 Ok(ExternalInstanceType::Memory(MemoryType::new(
187 limit.min(),
188 limit.max(),
189 limit.shared(),
190 )?))
191 }
192 }
193 }
194 ExternalInstanceType::Table(_) => {
195 let ctx_tab_ty = unsafe {
196 ffi::WasmEdge_ImportTypeGetTableType(self.module.inner.0, self.inner.0)
197 };
198 match ctx_tab_ty.is_null() {
199 true => Err(Box::new(WasmEdgeError::Import(ImportError::TableType(
200 "Fail to get the table type".into(),
201 )))),
202 false => {
203 let elem_ty = unsafe { ffi::WasmEdge_TableTypeGetRefType(ctx_tab_ty) };
205 let elem_ty = RefType::from(ValType::from(elem_ty));
206
207 let limit = unsafe { ffi::WasmEdge_TableTypeGetLimit(ctx_tab_ty) };
209 let limit = WasmEdgeLimit::from_context(limit);
210
211 Ok(ExternalInstanceType::Table(TableType::new(
212 elem_ty,
213 limit.min(),
214 limit.max(),
215 )))
216 }
217 }
218 }
219 }
220 }
221
222 pub fn name(&self) -> Cow<'_, str> {
224 let c_name = unsafe {
225 let raw_name = ffi::WasmEdge_ImportTypeGetExternalName(self.inner.0);
226 CStr::from_ptr(raw_name.Buf)
227 };
228 c_name.to_string_lossy()
229 }
230
231 pub fn module_name(&self) -> Cow<'_, str> {
233 let c_name = unsafe {
234 let raw_name = ffi::WasmEdge_ImportTypeGetModuleName(self.inner.0);
235 CStr::from_ptr(raw_name.Buf)
236 };
237 c_name.to_string_lossy()
238 }
239
240 #[cfg(feature = "ffi")]
242 #[cfg_attr(docsrs, doc(cfg(feature = "ffi")))]
243 pub fn as_ptr(&self) -> *const ffi::WasmEdge_ImportTypeContext {
244 self.inner.0 as *const _
245 }
246}
247
248#[derive(Debug)]
249pub(crate) struct InnerImportType(pub(crate) *const ffi::WasmEdge_ImportTypeContext);
250unsafe impl Send for InnerImportType {}
251unsafe impl Sync for InnerImportType {}
252
253#[derive(Debug)]
255pub struct ExportType<'module> {
256 pub(crate) inner: InnerExportType,
257 pub(crate) module: &'module Module,
258}
259
260impl ExportType<'_> {
261 pub fn ty(&self) -> WasmEdgeResult<ExternalInstanceType> {
263 let ty = unsafe { ffi::WasmEdge_ExportTypeGetExternalType(self.inner.0) };
264 let ty: ExternalInstanceType = ty.into();
265 match ty {
266 ExternalInstanceType::Func(_) => {
267 let ctx_func_ty = unsafe {
268 ffi::WasmEdge_ExportTypeGetFunctionType(self.module.inner.0, self.inner.0)
269 };
270 match ctx_func_ty.is_null() {
271 true => Err(Box::new(WasmEdgeError::Export(ExportError::FuncType(
272 "Fail to get the function type".into(),
273 )))),
274 false => {
275 let args_len = unsafe {
277 ffi::WasmEdge_FunctionTypeGetParametersLength(ctx_func_ty) as usize
278 };
279 let mut args = Vec::with_capacity(args_len);
280 unsafe {
281 ffi::WasmEdge_FunctionTypeGetParameters(
282 ctx_func_ty,
283 args.as_mut_ptr(),
284 args_len as u32,
285 );
286 args.set_len(args_len);
287 }
288 let args: Vec<ValType> = args.into_iter().map(Into::into).collect();
289
290 let returns_len = unsafe {
292 ffi::WasmEdge_FunctionTypeGetReturnsLength(ctx_func_ty) as usize
293 };
294 let mut returns = Vec::with_capacity(returns_len);
295 unsafe {
296 ffi::WasmEdge_FunctionTypeGetReturns(
297 ctx_func_ty,
298 returns.as_mut_ptr(),
299 returns_len as u32,
300 );
301 returns.set_len(returns_len);
302 }
303 let returns: Vec<ValType> = returns.into_iter().map(Into::into).collect();
304
305 Ok(ExternalInstanceType::Func(FuncType::new(args, returns)))
306 }
307 }
308 }
309 ExternalInstanceType::Table(_) => {
310 let ctx_tab_ty = unsafe {
311 ffi::WasmEdge_ExportTypeGetTableType(self.module.inner.0, self.inner.0)
312 };
313 match ctx_tab_ty.is_null() {
314 true => Err(Box::new(WasmEdgeError::Export(ExportError::TableType(
315 "Fail to get the function type".into(),
316 )))),
317 false => {
318 let elem_ty = unsafe { ffi::WasmEdge_TableTypeGetRefType(ctx_tab_ty) };
320 let elem_ty = RefType::from(ValType::from(elem_ty));
321
322 let limit = unsafe { ffi::WasmEdge_TableTypeGetLimit(ctx_tab_ty) };
324 let limit = WasmEdgeLimit::from_context(limit);
325
326 Ok(ExternalInstanceType::Table(TableType::new(
327 elem_ty,
328 limit.min(),
329 limit.max(),
330 )))
331 }
332 }
333 }
334 ExternalInstanceType::Memory(_) => {
335 let ctx_mem_ty = unsafe {
336 ffi::WasmEdge_ExportTypeGetMemoryType(self.module.inner.0, self.inner.0)
337 };
338 match ctx_mem_ty.is_null() {
339 true => Err(Box::new(WasmEdgeError::Export(ExportError::MemType(
340 "Fail to get the function type".into(),
341 )))),
342 false => {
343 let limit = unsafe { ffi::WasmEdge_MemoryTypeGetLimit(ctx_mem_ty) };
344 let limit = WasmEdgeLimit::from_context(limit);
345
346 Ok(ExternalInstanceType::Memory(MemoryType::new(
347 limit.min(),
348 limit.max(),
349 limit.shared(),
350 )?))
351 }
352 }
353 }
354 ExternalInstanceType::Global(_) => {
355 let ctx_global_ty = unsafe {
356 ffi::WasmEdge_ExportTypeGetGlobalType(self.module.inner.0, self.inner.0)
357 };
358 match ctx_global_ty.is_null() {
359 true => Err(Box::new(WasmEdgeError::Export(ExportError::GlobalType(
360 "Fail to get the function type".into(),
361 )))),
362 false => {
363 let val = unsafe { ffi::WasmEdge_GlobalTypeGetValType(ctx_global_ty) };
365 let val_ty: ValType = val.into();
366
367 let val = unsafe { ffi::WasmEdge_GlobalTypeGetMutability(ctx_global_ty) };
369 let mutability: Mutability = val.into();
370
371 Ok(ExternalInstanceType::Global(GlobalType::new(
372 val_ty, mutability,
373 )))
374 }
375 }
376 }
377 }
378 }
379
380 pub fn name(&self) -> Cow<'_, str> {
382 let c_name = unsafe {
383 let raw_name = ffi::WasmEdge_ExportTypeGetExternalName(self.inner.0);
384 CStr::from_ptr(raw_name.Buf)
385 };
386 c_name.to_string_lossy()
387 }
388}
389
390#[derive(Debug)]
391pub(crate) struct InnerExportType(pub(crate) *const ffi::WasmEdge_ExportTypeContext);
392unsafe impl Send for InnerExportType {}
393unsafe impl Sync for InnerExportType {}
394
395#[cfg(test)]
396mod tests {
397 use crate::{Config, Loader};
398 use std::{
399 sync::{Arc, Mutex},
400 thread,
401 };
402 use wasmedge_types::{ExternalInstanceType, Mutability, RefType, ValType};
403
404 #[ignore = "need to update `import.wat`"]
405 #[test]
406 fn test_module_import() {
407 let path = std::env::current_dir()
408 .unwrap()
409 .ancestors()
410 .nth(2)
411 .unwrap()
412 .join("examples/wasmedge-sys/data/import.wat");
413
414 let result = Config::create();
415 assert!(result.is_ok());
416 let mut config = result.unwrap();
417 config.bulk_memory_operations(true);
418 assert!(config.bulk_memory_operations_enabled());
419
420 let result = Loader::create(Some(&config));
422 assert!(result.is_ok());
423 let loader = result.unwrap();
424 let result = loader.from_file(path);
425 assert!(result.is_ok());
426 let module = result.unwrap();
427 assert!(!module.inner.0.is_null());
428
429 assert_eq!(module.count_of_imports(), 14);
432 let imports = module.imports();
433
434 let result = imports[0].ty();
436 assert!(result.is_ok());
437 let ty = result.unwrap();
438 matches!(ty, ExternalInstanceType::Func(_));
439 assert_eq!(imports[0].name(), "func-add");
440 assert_eq!(imports[0].module_name(), "extern");
441
442 let result = imports[1].ty();
443 assert!(result.is_ok());
444 matches!(result.unwrap(), ExternalInstanceType::Func(_));
445 assert_eq!(imports[1].name(), "func-sub");
446 assert_eq!(imports[1].module_name(), "extern");
447
448 let result = imports[2].ty();
449 assert!(result.is_ok());
450 matches!(result.unwrap(), ExternalInstanceType::Func(_));
451 assert_eq!(imports[2].name(), "func-mul");
452 assert_eq!(imports[2].module_name(), "extern");
453
454 let result = imports[3].ty();
455 assert!(result.is_ok());
456 matches!(result.unwrap(), ExternalInstanceType::Func(_));
457 assert_eq!(imports[3].name(), "func-div");
458 assert_eq!(imports[3].module_name(), "extern");
459
460 let result = imports[4].ty();
461 assert!(result.is_ok());
462 matches!(result.unwrap(), ExternalInstanceType::Func(_));
463 assert_eq!(imports[4].name(), "func-term");
464 assert_eq!(imports[4].module_name(), "extern");
465
466 let result = imports[5].ty();
467 assert!(result.is_ok());
468 matches!(result.unwrap(), ExternalInstanceType::Func(_));
469 assert_eq!(imports[5].name(), "func-fail");
470 assert_eq!(imports[5].module_name(), "extern");
471
472 let result = imports[6].ty();
473 assert!(result.is_ok());
474 matches!(result.unwrap(), ExternalInstanceType::Global(_));
475 assert_eq!(imports[6].name(), "glob-i32");
476 assert_eq!(imports[6].module_name(), "dummy");
477
478 let result = imports[7].ty();
479 assert!(result.is_ok());
480 matches!(result.unwrap(), ExternalInstanceType::Global(_));
481 assert_eq!(imports[7].name(), "glob-i64");
482 assert_eq!(imports[7].module_name(), "dummy");
483
484 let result = imports[8].ty();
485 assert!(result.is_ok());
486 matches!(result.unwrap(), ExternalInstanceType::Global(_));
487 assert_eq!(imports[8].name(), "glob-f32");
488 assert_eq!(imports[8].module_name(), "dummy");
489
490 let result = imports[9].ty();
491 assert!(result.is_ok());
492 matches!(result.unwrap(), ExternalInstanceType::Global(_));
493 assert_eq!(imports[9].name(), "glob-f64");
494 assert_eq!(imports[9].module_name(), "dummy");
495
496 let result = imports[10].ty();
497 assert!(result.is_ok());
498 matches!(result.unwrap(), ExternalInstanceType::Table(_));
499 assert_eq!(imports[10].name(), "tab-func");
500 assert_eq!(imports[10].module_name(), "dummy");
501
502 let result = imports[11].ty();
503 assert!(result.is_ok());
504 matches!(result.unwrap(), ExternalInstanceType::Table(_));
505 assert_eq!(imports[11].name(), "tab-ext");
506 assert_eq!(imports[11].module_name(), "dummy");
507
508 let result = imports[12].ty();
509 assert!(result.is_ok());
510 matches!(result.unwrap(), ExternalInstanceType::Memory(_));
511 assert_eq!(imports[12].name(), "mem1");
512 assert_eq!(imports[12].module_name(), "dummy");
513
514 let result = imports[13].ty();
515 assert!(result.is_ok());
516 matches!(result.unwrap(), ExternalInstanceType::Memory(_));
517 assert_eq!(imports[13].name(), "mem2");
518 assert_eq!(imports[13].module_name(), "dummy");
519
520 let result = imports[4].ty();
522 assert!(result.is_ok());
523 let ty = result.unwrap();
524 matches!(ty, ExternalInstanceType::Func(_));
525 if let ExternalInstanceType::Func(func_ty) = ty {
526 assert_eq!(func_ty.returns_len(), 1);
527 }
528
529 let result = imports[11].ty();
531 assert!(result.is_ok());
532 let ty = result.unwrap();
533 matches!(ty, ExternalInstanceType::Table(_));
534 if let ExternalInstanceType::Table(table_ty) = ty {
535 assert_eq!(table_ty.elem_ty(), RefType::ExternRef);
536 assert_eq!(table_ty.minimum(), 10);
537 assert_eq!(table_ty.maximum(), Some(30));
538 }
539
540 let result = imports[13].ty();
542 assert!(result.is_ok());
543 let ty = result.unwrap();
544 matches!(ty, ExternalInstanceType::Memory(_));
545 if let ExternalInstanceType::Memory(mem_ty) = ty {
546 assert_eq!(mem_ty.minimum(), 2);
547 assert_eq!(mem_ty.maximum(), None);
548 }
549
550 let result = imports[7].ty();
552 assert!(result.is_ok());
553 let ty = result.unwrap();
554 matches!(ty, ExternalInstanceType::Global(_));
555 if let ExternalInstanceType::Global(global_ty) = ty {
556 assert_eq!(global_ty.value_ty(), ValType::I64);
557 assert_eq!(global_ty.mutability(), Mutability::Const);
558 }
559 }
560
561 #[ignore = "need to update `import.wat`"]
562 #[test]
563 fn test_module_export() {
564 let path = std::env::current_dir()
565 .unwrap()
566 .ancestors()
567 .nth(2)
568 .unwrap()
569 .join("examples/wasmedge-sys/data/import.wat");
570
571 let result = Config::create();
572 assert!(result.is_ok());
573 let mut config = result.unwrap();
574 config.bulk_memory_operations(true);
575 assert!(config.bulk_memory_operations_enabled());
576
577 let result = Loader::create(Some(&config));
579 assert!(result.is_ok());
580 let loader = result.unwrap();
581 let result = loader.from_file(path);
582 assert!(result.is_ok());
583 let module = result.unwrap();
584 assert!(!module.inner.0.is_null());
585
586 assert_eq!(module.count_of_exports(), 16);
589 let exports = module.export();
590
591 let result = exports[0].ty();
593 assert!(result.is_ok());
594 matches!(result.unwrap(), ExternalInstanceType::Func(_));
595 assert_eq!(exports[0].name(), "func-1");
596
597 let result = exports[1].ty();
598 assert!(result.is_ok());
599 matches!(result.unwrap(), ExternalInstanceType::Func(_));
600 assert_eq!(exports[1].name(), "func-2");
601
602 let result = exports[2].ty();
603 assert!(result.is_ok());
604 matches!(result.unwrap(), ExternalInstanceType::Func(_));
605 assert_eq!(exports[2].name(), "func-3");
606
607 let result = exports[3].ty();
608 assert!(result.is_ok());
609 matches!(result.unwrap(), ExternalInstanceType::Func(_));
610 assert_eq!(exports[3].name(), "func-4");
611
612 assert_eq!(module.count_of_exports(), 16);
613
614 let result = exports[4].ty();
615 assert!(result.is_ok());
616 matches!(result.unwrap(), ExternalInstanceType::Func(_));
617 assert_eq!(exports[4].name(), "func-add");
618
619 let result = exports[5].ty();
620 assert!(result.is_ok());
621 matches!(result.unwrap(), ExternalInstanceType::Func(_));
622 assert_eq!(exports[5].name(), "func-mul-2");
623
624 let result = exports[6].ty();
625 assert!(result.is_ok());
626 matches!(result.unwrap(), ExternalInstanceType::Func(_));
627 assert_eq!(exports[6].name(), "func-call-indirect");
628
629 let result = exports[7].ty();
630 assert!(result.is_ok());
631 matches!(result.unwrap(), ExternalInstanceType::Func(_));
632 assert_eq!(exports[7].name(), "func-host-add");
633
634 let result = exports[8].ty();
635 assert!(result.is_ok());
636 matches!(result.unwrap(), ExternalInstanceType::Func(_));
637 assert_eq!(exports[8].name(), "func-host-sub");
638
639 let result = exports[9].ty();
640 assert!(result.is_ok());
641 matches!(result.unwrap(), ExternalInstanceType::Func(_));
642 assert_eq!(exports[9].name(), "func-host-mul");
643
644 let result = exports[10].ty();
645 assert!(result.is_ok());
646 matches!(result.unwrap(), ExternalInstanceType::Func(_));
647 assert_eq!(exports[10].name(), "func-host-div");
648
649 let result = exports[11].ty();
650 assert!(result.is_ok());
651 matches!(result.unwrap(), ExternalInstanceType::Table(_));
652 assert_eq!(exports[11].name(), "tab-func");
653
654 let result = exports[12].ty();
655 assert!(result.is_ok());
656 matches!(result.unwrap(), ExternalInstanceType::Table(_));
657 assert_eq!(exports[12].name(), "tab-ext");
658
659 let result = exports[13].ty();
660 assert!(result.is_ok());
661 matches!(result.unwrap(), ExternalInstanceType::Memory(_));
662 assert_eq!(exports[13].name(), "mem");
663
664 let result = exports[14].ty();
665 assert!(result.is_ok());
666 matches!(result.unwrap(), ExternalInstanceType::Global(_));
667 assert_eq!(exports[14].name(), "glob-mut-i32");
668
669 let result = exports[15].ty();
670 assert!(result.is_ok());
671 matches!(result.unwrap(), ExternalInstanceType::Global(_));
672 assert_eq!(exports[15].name(), "glob-const-f32");
673
674 let result = exports[4].ty();
676 assert!(result.is_ok());
677 let ty = result.unwrap();
678 matches!(ty, ExternalInstanceType::Func(_));
679 if let ExternalInstanceType::Func(func_ty) = ty {
680 assert_eq!(func_ty.args_len(), 2);
681 assert_eq!(func_ty.returns_len(), 1);
682 }
683
684 let result = exports[12].ty();
686 assert!(result.is_ok());
687 let ty = result.unwrap();
688 matches!(ty, ExternalInstanceType::Table(_));
689 if let ExternalInstanceType::Table(table_ty) = ty {
690 assert_eq!(table_ty.elem_ty(), RefType::ExternRef);
691 assert_eq!(table_ty.minimum(), 10);
692 assert_eq!(table_ty.maximum(), None);
693 }
694
695 let result = exports[13].ty();
697 assert!(result.is_ok());
698 let ty = result.unwrap();
699 matches!(ty, ExternalInstanceType::Memory(_));
700 if let ExternalInstanceType::Memory(mem_ty) = ty {
701 assert_eq!(mem_ty.minimum(), 1);
702 assert_eq!(mem_ty.maximum(), Some(3));
703 }
704
705 let result = exports[15].ty();
707 assert!(result.is_ok());
708 let ty = result.unwrap();
709 matches!(ty, ExternalInstanceType::Global(_));
710 if let ExternalInstanceType::Global(global_ty) = ty {
711 assert_eq!(global_ty.value_ty(), ValType::F32);
712 assert_eq!(global_ty.mutability(), Mutability::Const);
713 }
714 }
715
716 #[ignore = "need to update `import.wat`"]
717 #[test]
718 fn test_module_send() {
719 let path = std::env::current_dir()
720 .unwrap()
721 .ancestors()
722 .nth(2)
723 .unwrap()
724 .join("examples/wasmedge-sys/data/import.wat");
725
726 let result = Config::create();
727 assert!(result.is_ok());
728 let mut config = result.unwrap();
729 config.bulk_memory_operations(true);
730 assert!(config.bulk_memory_operations_enabled());
731
732 let result = Loader::create(Some(&config));
734 assert!(result.is_ok());
735 let loader = result.unwrap();
736 let result = loader.from_file(path);
737 assert!(result.is_ok());
738 let module = result.unwrap();
739 assert!(!module.inner.0.is_null());
740
741 let handle = thread::spawn(move || {
742 assert_eq!(module.count_of_exports(), 16);
745 let exports = module.export();
746
747 let result = exports[0].ty();
749 assert!(result.is_ok());
750 matches!(result.unwrap(), ExternalInstanceType::Func(_));
751 assert_eq!(exports[0].name(), "func-1");
752
753 let result = exports[1].ty();
754 assert!(result.is_ok());
755 matches!(result.unwrap(), ExternalInstanceType::Func(_));
756 assert_eq!(exports[1].name(), "func-2");
757
758 let result = exports[2].ty();
759 assert!(result.is_ok());
760 matches!(result.unwrap(), ExternalInstanceType::Func(_));
761 assert_eq!(exports[2].name(), "func-3");
762
763 let result = exports[3].ty();
764 assert!(result.is_ok());
765 matches!(result.unwrap(), ExternalInstanceType::Func(_));
766 assert_eq!(exports[3].name(), "func-4");
767
768 assert_eq!(module.count_of_exports(), 16);
769
770 let result = exports[4].ty();
771 assert!(result.is_ok());
772 matches!(result.unwrap(), ExternalInstanceType::Func(_));
773 assert_eq!(exports[4].name(), "func-add");
774
775 let result = exports[5].ty();
776 assert!(result.is_ok());
777 matches!(result.unwrap(), ExternalInstanceType::Func(_));
778 assert_eq!(exports[5].name(), "func-mul-2");
779
780 let result = exports[6].ty();
781 assert!(result.is_ok());
782 matches!(result.unwrap(), ExternalInstanceType::Func(_));
783 assert_eq!(exports[6].name(), "func-call-indirect");
784
785 let result = exports[7].ty();
786 assert!(result.is_ok());
787 matches!(result.unwrap(), ExternalInstanceType::Func(_));
788 assert_eq!(exports[7].name(), "func-host-add");
789
790 let result = exports[8].ty();
791 assert!(result.is_ok());
792 matches!(result.unwrap(), ExternalInstanceType::Func(_));
793 assert_eq!(exports[8].name(), "func-host-sub");
794
795 let result = exports[9].ty();
796 assert!(result.is_ok());
797 matches!(result.unwrap(), ExternalInstanceType::Func(_));
798 assert_eq!(exports[9].name(), "func-host-mul");
799
800 let result = exports[10].ty();
801 assert!(result.is_ok());
802 matches!(result.unwrap(), ExternalInstanceType::Func(_));
803 assert_eq!(exports[10].name(), "func-host-div");
804
805 let result = exports[11].ty();
806 assert!(result.is_ok());
807 matches!(result.unwrap(), ExternalInstanceType::Table(_));
808 assert_eq!(exports[11].name(), "tab-func");
809
810 let result = exports[12].ty();
811 assert!(result.is_ok());
812 matches!(result.unwrap(), ExternalInstanceType::Table(_));
813 assert_eq!(exports[12].name(), "tab-ext");
814
815 let result = exports[13].ty();
816 assert!(result.is_ok());
817 matches!(result.unwrap(), ExternalInstanceType::Memory(_));
818 assert_eq!(exports[13].name(), "mem");
819
820 let result = exports[14].ty();
821 assert!(result.is_ok());
822 matches!(result.unwrap(), ExternalInstanceType::Global(_));
823 assert_eq!(exports[14].name(), "glob-mut-i32");
824
825 let result = exports[15].ty();
826 assert!(result.is_ok());
827 matches!(result.unwrap(), ExternalInstanceType::Global(_));
828 assert_eq!(exports[15].name(), "glob-const-f32");
829
830 let result = exports[4].ty();
832 assert!(result.is_ok());
833 let ty = result.unwrap();
834 matches!(ty, ExternalInstanceType::Func(_));
835 if let ExternalInstanceType::Func(func_ty) = ty {
836 assert_eq!(func_ty.args_len(), 2);
837 assert_eq!(func_ty.returns_len(), 1);
838 }
839
840 let result = exports[12].ty();
842 assert!(result.is_ok());
843 let ty = result.unwrap();
844 matches!(ty, ExternalInstanceType::Table(_));
845 if let ExternalInstanceType::Table(table_ty) = ty {
846 assert_eq!(table_ty.elem_ty(), RefType::ExternRef);
847 assert_eq!(table_ty.minimum(), 10);
848 assert_eq!(table_ty.maximum(), None);
849 }
850
851 let result = exports[13].ty();
853 assert!(result.is_ok());
854 let ty = result.unwrap();
855 matches!(ty, ExternalInstanceType::Memory(_));
856 if let ExternalInstanceType::Memory(mem_ty) = ty {
857 assert_eq!(mem_ty.minimum(), 1);
858 assert_eq!(mem_ty.maximum(), Some(3));
859 }
860
861 let result = exports[15].ty();
863 assert!(result.is_ok());
864 let ty = result.unwrap();
865 matches!(ty, ExternalInstanceType::Global(_));
866 if let ExternalInstanceType::Global(global_ty) = ty {
867 assert_eq!(global_ty.value_ty(), ValType::F32);
868 assert_eq!(global_ty.mutability(), Mutability::Const);
869 }
870 });
871
872 handle.join().unwrap();
873 }
874
875 #[ignore = "need to update `import.wat`"]
876 #[test]
877 fn test_module_sync() {
878 let path = std::env::current_dir()
879 .unwrap()
880 .ancestors()
881 .nth(2)
882 .unwrap()
883 .join("examples/wasmedge-sys/data/import.wat");
884
885 let result = Config::create();
886 assert!(result.is_ok());
887 let mut config = result.unwrap();
888 config.bulk_memory_operations(true);
889 assert!(config.bulk_memory_operations_enabled());
890
891 let result = Loader::create(Some(&config));
893 assert!(result.is_ok());
894 let loader = result.unwrap();
895 let result = loader.from_file(path);
896 assert!(result.is_ok());
897 let module = Arc::new(Mutex::new(result.unwrap()));
898
899 let module_cloned = Arc::clone(&module);
900 let handle = thread::spawn(move || {
901 let result = module_cloned.lock();
902 assert!(result.is_ok());
903 let module = result.unwrap();
904
905 assert_eq!(module.count_of_exports(), 16);
908 let exports = module.export();
909
910 let result = exports[0].ty();
912 assert!(result.is_ok());
913 matches!(result.unwrap(), ExternalInstanceType::Func(_));
914 assert_eq!(exports[0].name(), "func-1");
915
916 let result = exports[1].ty();
917 assert!(result.is_ok());
918 matches!(result.unwrap(), ExternalInstanceType::Func(_));
919 assert_eq!(exports[1].name(), "func-2");
920
921 let result = exports[2].ty();
922 assert!(result.is_ok());
923 matches!(result.unwrap(), ExternalInstanceType::Func(_));
924 assert_eq!(exports[2].name(), "func-3");
925
926 let result = exports[3].ty();
927 assert!(result.is_ok());
928 matches!(result.unwrap(), ExternalInstanceType::Func(_));
929 assert_eq!(exports[3].name(), "func-4");
930
931 assert_eq!(module.count_of_exports(), 16);
932
933 let result = exports[4].ty();
934 assert!(result.is_ok());
935 matches!(result.unwrap(), ExternalInstanceType::Func(_));
936 assert_eq!(exports[4].name(), "func-add");
937
938 let result = exports[5].ty();
939 assert!(result.is_ok());
940 matches!(result.unwrap(), ExternalInstanceType::Func(_));
941 assert_eq!(exports[5].name(), "func-mul-2");
942
943 let result = exports[6].ty();
944 assert!(result.is_ok());
945 matches!(result.unwrap(), ExternalInstanceType::Func(_));
946 assert_eq!(exports[6].name(), "func-call-indirect");
947
948 let result = exports[7].ty();
949 assert!(result.is_ok());
950 matches!(result.unwrap(), ExternalInstanceType::Func(_));
951 assert_eq!(exports[7].name(), "func-host-add");
952
953 let result = exports[8].ty();
954 assert!(result.is_ok());
955 matches!(result.unwrap(), ExternalInstanceType::Func(_));
956 assert_eq!(exports[8].name(), "func-host-sub");
957
958 let result = exports[9].ty();
959 assert!(result.is_ok());
960 matches!(result.unwrap(), ExternalInstanceType::Func(_));
961 assert_eq!(exports[9].name(), "func-host-mul");
962
963 let result = exports[10].ty();
964 assert!(result.is_ok());
965 matches!(result.unwrap(), ExternalInstanceType::Func(_));
966 assert_eq!(exports[10].name(), "func-host-div");
967
968 let result = exports[11].ty();
969 assert!(result.is_ok());
970 matches!(result.unwrap(), ExternalInstanceType::Table(_));
971 assert_eq!(exports[11].name(), "tab-func");
972
973 let result = exports[12].ty();
974 assert!(result.is_ok());
975 matches!(result.unwrap(), ExternalInstanceType::Table(_));
976 assert_eq!(exports[12].name(), "tab-ext");
977
978 let result = exports[13].ty();
979 assert!(result.is_ok());
980 matches!(result.unwrap(), ExternalInstanceType::Memory(_));
981 assert_eq!(exports[13].name(), "mem");
982
983 let result = exports[14].ty();
984 assert!(result.is_ok());
985 matches!(result.unwrap(), ExternalInstanceType::Global(_));
986 assert_eq!(exports[14].name(), "glob-mut-i32");
987
988 let result = exports[15].ty();
989 assert!(result.is_ok());
990 let ty = result.unwrap();
991 matches!(ty, ExternalInstanceType::Global(_));
992 assert_eq!(exports[15].name(), "glob-const-f32");
993
994 let result = exports[4].ty();
996 assert!(result.is_ok());
997 let ty = result.unwrap();
998 matches!(ty, ExternalInstanceType::Func(_));
999 if let ExternalInstanceType::Func(func_ty) = ty {
1000 assert_eq!(func_ty.args_len(), 2);
1001 assert_eq!(func_ty.returns_len(), 1);
1002 }
1003
1004 let result = exports[12].ty();
1006 assert!(result.is_ok());
1007 let ty = result.unwrap();
1008 matches!(ty, ExternalInstanceType::Table(_));
1009 if let ExternalInstanceType::Table(table_ty) = ty {
1010 assert_eq!(table_ty.elem_ty(), RefType::ExternRef);
1011 assert_eq!(table_ty.minimum(), 10);
1012 assert_eq!(table_ty.maximum(), None);
1013 }
1014
1015 let result = exports[13].ty();
1017 assert!(result.is_ok());
1018 let ty = result.unwrap();
1019 matches!(ty, ExternalInstanceType::Memory(_));
1020 if let ExternalInstanceType::Memory(mem_ty) = ty {
1021 assert_eq!(mem_ty.minimum(), 1);
1022 assert_eq!(mem_ty.maximum(), Some(3));
1023 }
1024
1025 let result = exports[15].ty();
1027 assert!(result.is_ok());
1028 let ty = result.unwrap();
1029 matches!(ty, ExternalInstanceType::Global(_));
1030 if let ExternalInstanceType::Global(global_ty) = ty {
1031 assert_eq!(global_ty.value_ty(), ValType::F32);
1032 assert_eq!(global_ty.mutability(), Mutability::Const);
1033 }
1034 });
1035
1036 handle.join().unwrap();
1037 }
1038}