1use crate::{
2 instance::function::SyncFn, AsInstance, CallingFrame, FuncType, Function, ImportModule,
3 Instance, Memory, WasmEdgeResult, WasmValue,
4};
5use async_wasi::snapshots::{
6 common::{
7 error::Errno,
8 memory::WasmPtr,
9 types::{__wasi_ciovec_t, __wasi_size_t},
10 },
11 preview_1 as p, WasiCtx,
12};
13use std::{
14 future::Future,
15 ops::{Deref, DerefMut},
16};
17use wasmedge_types::{
18 error::{CoreCommonError, CoreError, CoreExecutionError},
19 ValType,
20};
21
22use super::function::{AsyncFn, AsyncFunction};
23
24#[derive(Debug)]
25pub struct AsyncInstance(pub(crate) Instance);
26
27impl AsRef<Instance> for AsyncInstance {
28 fn as_ref(&self) -> &Instance {
29 &self.0
30 }
31}
32
33impl AsMut<Instance> for AsyncInstance {
34 fn as_mut(&mut self) -> &mut Instance {
35 &mut self.0
36 }
37}
38
39#[derive(Debug)]
40pub struct AsyncImportObject<T: Send>(ImportModule<T>);
41impl<T: Send> Deref for AsyncImportObject<T> {
42 type Target = ImportModule<T>;
43 fn deref(&self) -> &Self::Target {
44 &self.0
45 }
46}
47impl<T: Send> DerefMut for AsyncImportObject<T> {
48 fn deref_mut(&mut self) -> &mut Self::Target {
49 &mut self.0
50 }
51}
52
53impl<T: Send> AsyncImportObject<T> {
54 pub fn create(name: impl AsRef<str>, data: Box<T>) -> WasmEdgeResult<Self> {
55 let inner = ImportModule::create(name, data)?;
56 Ok(AsyncImportObject(inner))
57 }
58
59 pub fn add_async_func(&mut self, name: impl AsRef<str>, func: AsyncFunction) {
60 self.0.add_func(name, func.0);
61 }
62}
63impl<T: Send> AsRef<ImportModule<T>> for AsyncImportObject<T> {
64 fn as_ref(&self) -> &ImportModule<T> {
65 &self.0
66 }
67}
68impl<T: Send> AsMut<ImportModule<T>> for AsyncImportObject<T> {
69 fn as_mut(&mut self) -> &mut ImportModule<T> {
70 &mut self.0
71 }
72}
73
74impl<T: Send> AsInstance for AsyncImportObject<T> {
75 unsafe fn as_ptr(&self) -> *const crate::ffi::WasmEdge_ModuleInstanceContext {
76 self.0.as_ptr()
77 }
78}
79
80#[derive(Debug)]
82pub struct AsyncWasiModule(AsyncImportObject<WasiCtx>);
83
84impl AsRef<AsyncImportObject<WasiCtx>> for AsyncWasiModule {
85 fn as_ref(&self) -> &AsyncImportObject<WasiCtx> {
86 &self.0
87 }
88}
89
90impl AsMut<AsyncImportObject<WasiCtx>> for AsyncWasiModule {
91 fn as_mut(&mut self) -> &mut AsyncImportObject<WasiCtx> {
92 &mut self.0
93 }
94}
95
96impl AsyncWasiModule {
97 pub fn create(
109 args: Option<Vec<impl AsRef<str>>>,
110 envs: Option<Vec<(impl AsRef<str>, impl AsRef<str>)>>,
111 ) -> WasmEdgeResult<Self> {
112 let mut wasi_ctx = WasiCtx::new();
114
115 if let Some(args) = args {
117 wasi_ctx.push_args(args.iter().map(|x| x.as_ref().to_string()).collect());
118 }
119 if let Some(envs) = envs {
120 wasi_ctx.push_envs(
121 envs.iter()
122 .map(|(k, v)| format!("{}={}", k.as_ref(), v.as_ref()))
123 .collect(),
124 );
125 }
126
127 Self::create_from_wasi_context(wasi_ctx)
128 }
129
130 pub fn create_from_wasi_context(wasi_ctx: WasiCtx) -> WasmEdgeResult<Self> {
140 let name = "wasi_snapshot_preview1";
142
143 let mut async_wasi_module = Self(AsyncImportObject::create(name, Box::new(wasi_ctx))?);
144
145 for wasi_func in wasi_impls() {
147 match wasi_func {
148 WasiFunc::SyncFn(name, (ty_args, ty_rets), real_fn) => {
149 let func_ty = FuncType::new(ty_args, ty_rets);
150
151 let func = unsafe {
152 Function::create_sync_func(
153 &func_ty,
154 real_fn,
155 async_wasi_module.0.get_host_data_mut(),
156 0,
157 )
158 }?;
159
160 async_wasi_module.0.add_func(&name, func);
161 }
162 WasiFunc::AsyncFn(name, (ty_args, ty_rets), real_async_fn) => {
163 let func_ty = FuncType::new(ty_args, ty_rets);
164
165 let func = AsyncFunction::create_async_func(
166 &func_ty,
167 real_async_fn,
168 async_wasi_module.0.get_host_data_mut(),
169 0,
170 )?;
171
172 async_wasi_module.0.add_async_func(&name, func);
173 }
174 }
175 }
176
177 Ok(async_wasi_module)
178 }
179
180 pub fn name(&self) -> &str {
182 "wasi_snapshot_preview1"
183 }
184
185 pub fn exit_code(&self) -> u32 {
189 self.0.get_host_data().exit_code
190 }
191}
192
193fn args_get(
196 data: &mut WasiCtx,
197 _inst: &mut Instance,
198 frame: &mut CallingFrame,
199 args: Vec<WasmValue>,
200) -> Result<Vec<WasmValue>, CoreError> {
201 let mut mem = frame
202 .memory_mut(0)
203 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
204
205 if let Some([argv, argv_buf]) = args.get(0..2) {
206 let argv = argv.to_i32() as usize;
207 let argv_buf = argv_buf.to_i32() as usize;
208 Ok(to_wasm_return(p::args_get(
209 data,
210 &mut *mem,
211 WasmPtr::from(argv),
212 WasmPtr::from(argv_buf),
213 )))
214 } else {
215 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
216 }
217}
218
219fn args_sizes_get(
220 data: &mut WasiCtx,
221 _inst: &mut Instance,
222 frame: &mut CallingFrame,
223 args: Vec<WasmValue>,
224) -> Result<Vec<WasmValue>, CoreError> {
225 let mut mem = frame
226 .memory_mut(0)
227 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
228
229 if let Some([argc, argv_buf_size]) = args.get(0..2) {
230 let argc = argc.to_i32() as usize;
231 let argv_buf_size = argv_buf_size.to_i32() as usize;
232 Ok(to_wasm_return(p::args_sizes_get(
233 data,
234 &mut mem as &mut Memory,
235 WasmPtr::from(argc),
236 WasmPtr::from(argv_buf_size),
237 )))
238 } else {
239 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
240 }
241}
242
243fn environ_get(
244 data: &mut WasiCtx,
245 _inst: &mut Instance,
246 frame: &mut CallingFrame,
247 args: Vec<WasmValue>,
248) -> Result<Vec<WasmValue>, CoreError> {
249 let mut mem = frame
250 .memory_mut(0)
251 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
252
253 if let Some([p1, p2]) = args.get(0..2) {
254 let environ = p1.to_i32() as usize;
255 let environ_buf = p2.to_i32() as usize;
256 Ok(to_wasm_return(p::environ_get(
257 data,
258 &mut mem as &mut Memory,
259 WasmPtr::from(environ),
260 WasmPtr::from(environ_buf),
261 )))
262 } else {
263 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
264 }
265}
266
267fn environ_sizes_get(
268 data: &mut WasiCtx,
269 _inst: &mut Instance,
270 frame: &mut CallingFrame,
271 args: Vec<WasmValue>,
272) -> Result<Vec<WasmValue>, CoreError> {
273 let mut mem = frame
274 .memory_mut(0)
275 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
276
277 if let Some([p1, p2]) = args.get(0..2) {
278 let environ_count = p1.to_i32() as usize;
279 let environ_buf_size = p2.to_i32() as usize;
280 Ok(to_wasm_return(p::environ_sizes_get(
281 data,
282 &mut mem as &mut Memory,
283 WasmPtr::from(environ_count),
284 WasmPtr::from(environ_buf_size),
285 )))
286 } else {
287 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
288 }
289}
290
291fn clock_res_get(
292 data: &mut WasiCtx,
293 _inst: &mut Instance,
294 frame: &mut CallingFrame,
295 args: Vec<WasmValue>,
296) -> Result<Vec<WasmValue>, CoreError> {
297 let mut mem = frame
298 .memory_mut(0)
299 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
300
301 if let Some([p1, p2]) = args.get(0..2) {
302 let clock_id = p1.to_i32() as u32;
303 let resolution_ptr = p2.to_i32() as usize;
304 Ok(to_wasm_return(p::clock_res_get(
305 data,
306 &mut mem as &mut Memory,
307 clock_id,
308 WasmPtr::from(resolution_ptr),
309 )))
310 } else {
311 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
312 }
313}
314
315fn clock_time_get(
316 data: &mut WasiCtx,
317 _inst: &mut Instance,
318 frame: &mut CallingFrame,
319 args: Vec<WasmValue>,
320) -> Result<Vec<WasmValue>, CoreError> {
321 let mut mem = frame
322 .memory_mut(0)
323 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
324
325 if let Some([p1, p2, p3]) = args.get(0..3) {
326 let clock_id = p1.to_i32() as u32;
327 let precision = p2.to_i64() as u64;
328 let time_ptr = p3.to_i32() as usize;
329
330 Ok(to_wasm_return(p::clock_time_get(
331 data,
332 &mut mem as &mut Memory,
333 clock_id,
334 precision,
335 WasmPtr::from(time_ptr),
336 )))
337 } else {
338 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
339 }
340}
341
342fn random_get(
343 data: &mut WasiCtx,
344 _inst: &mut Instance,
345 frame: &mut CallingFrame,
346 args: Vec<WasmValue>,
347) -> Result<Vec<WasmValue>, CoreError> {
348 let mut mem = frame
349 .memory_mut(0)
350 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
351
352 if let Some([p1, p2]) = args.get(0..2) {
353 let buf = p1.to_i32() as usize;
354 let buf_len = p2.to_i32() as u32;
355
356 Ok(to_wasm_return(p::random_get(
357 data,
358 &mut mem as &mut Memory,
359 WasmPtr::from(buf),
360 buf_len,
361 )))
362 } else {
363 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
364 }
365}
366
367fn fd_prestat_get(
368 data: &mut WasiCtx,
369 _inst: &mut Instance,
370 frame: &mut CallingFrame,
371 args: Vec<WasmValue>,
372) -> Result<Vec<WasmValue>, CoreError> {
373 let mut mem = frame
374 .memory_mut(0)
375 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
376
377 if let Some([p1, p2]) = args.get(0..2) {
378 let fd = p1.to_i32();
379 let prestat_ptr = p2.to_i32() as usize;
380
381 Ok(to_wasm_return(p::fd_prestat_get(
382 data,
383 &mut mem as &mut Memory,
384 fd,
385 WasmPtr::from(prestat_ptr),
386 )))
387 } else {
388 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
389 }
390}
391
392fn fd_prestat_dir_name(
393 data: &mut WasiCtx,
394 _inst: &mut Instance,
395 frame: &mut CallingFrame,
396 args: Vec<WasmValue>,
397) -> Result<Vec<WasmValue>, CoreError> {
398 let mut mem = frame
399 .memory_mut(0)
400 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
401
402 if let Some([p1, p2, p3]) = args.get(0..3) {
403 let fd = p1.to_i32();
404 let path_buf_ptr = p2.to_i32() as usize;
405 let path_max_len = p3.to_i32() as u32;
406
407 Ok(to_wasm_return(p::fd_prestat_dir_name(
408 data,
409 &mut mem as &mut Memory,
410 fd,
411 WasmPtr::from(path_buf_ptr),
412 path_max_len,
413 )))
414 } else {
415 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
416 }
417}
418
419fn fd_renumber(
420 data: &mut WasiCtx,
421 _inst: &mut Instance,
422 frame: &mut CallingFrame,
423 args: Vec<WasmValue>,
424) -> Result<Vec<WasmValue>, CoreError> {
425 let mut mem = frame
426 .memory_mut(0)
427 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
428
429 if let Some([p1, p2]) = args.get(0..2) {
430 let from = p1.to_i32();
431 let to = p2.to_i32();
432
433 Ok(to_wasm_return(p::fd_renumber(
434 data,
435 &mut mem as &mut Memory,
436 from,
437 to,
438 )))
439 } else {
440 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
441 }
442}
443
444fn fd_advise(
445 data: &mut WasiCtx,
446 _inst: &mut Instance,
447 frame: &mut CallingFrame,
448 args: Vec<WasmValue>,
449) -> Result<Vec<WasmValue>, CoreError> {
450 let mut mem = frame
451 .memory_mut(0)
452 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
453
454 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
455 let fd = p1.to_i32();
456 let offset = p2.to_i64() as u64;
457 let len = p3.to_i64() as u64;
458 let advice = p4.to_i32() as u8;
459
460 Ok(to_wasm_return(p::fd_advise(
461 data,
462 &mut mem as &mut Memory,
463 fd,
464 offset,
465 len,
466 advice,
467 )))
468 } else {
469 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
470 }
471}
472
473fn fd_allocate(
474 data: &mut WasiCtx,
475 _inst: &mut Instance,
476 frame: &mut CallingFrame,
477 args: Vec<WasmValue>,
478) -> Result<Vec<WasmValue>, CoreError> {
479 let mut mem = frame
480 .memory_mut(0)
481 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
482
483 if let Some([p1, p2, p3]) = args.get(0..3) {
484 let fd = p1.to_i32();
485 let offset = p2.to_i64() as u64;
486 let len = p3.to_i64() as u64;
487
488 Ok(to_wasm_return(p::fd_allocate(
489 data,
490 &mut mem as &mut Memory,
491 fd,
492 offset,
493 len,
494 )))
495 } else {
496 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
497 }
498}
499
500fn fd_close(
501 data: &mut WasiCtx,
502 _inst: &mut Instance,
503 frame: &mut CallingFrame,
504 args: Vec<WasmValue>,
505) -> Result<Vec<WasmValue>, CoreError> {
506 let mut mem = frame
507 .memory_mut(0)
508 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
509
510 if let Some([p1]) = args.get(0..1) {
511 let fd = p1.to_i32();
512
513 Ok(to_wasm_return(p::fd_close(
514 data,
515 &mut mem as &mut Memory,
516 fd,
517 )))
518 } else {
519 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
520 }
521}
522
523fn fd_seek(
524 data: &mut WasiCtx,
525 _inst: &mut Instance,
526 frame: &mut CallingFrame,
527 args: Vec<WasmValue>,
528) -> Result<Vec<WasmValue>, CoreError> {
529 let mut mem = frame
530 .memory_mut(0)
531 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
532
533 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
534 let fd = p1.to_i32();
535 let offset = p2.to_i64();
536 let whence = p3.to_i32() as u8;
537 let newoffset_ptr = p4.to_i32() as usize;
538
539 Ok(to_wasm_return(p::fd_seek(
540 data,
541 &mut mem as &mut Memory,
542 fd,
543 offset,
544 whence,
545 WasmPtr::from(newoffset_ptr),
546 )))
547 } else {
548 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
549 }
550}
551
552fn fd_sync(
553 data: &mut WasiCtx,
554 _inst: &mut Instance,
555 frame: &mut CallingFrame,
556 args: Vec<WasmValue>,
557) -> Result<Vec<WasmValue>, CoreError> {
558 let mut mem = frame
559 .memory_mut(0)
560 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
561
562 if let Some([p1]) = args.get(0..1) {
563 let fd = p1.to_i32();
564
565 Ok(to_wasm_return(p::fd_sync(
566 data,
567 &mut mem as &mut Memory,
568 fd,
569 )))
570 } else {
571 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
572 }
573}
574
575fn fd_datasync(
576 data: &mut WasiCtx,
577 _inst: &mut Instance,
578 frame: &mut CallingFrame,
579 args: Vec<WasmValue>,
580) -> Result<Vec<WasmValue>, CoreError> {
581 let mut mem = frame
582 .memory_mut(0)
583 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
584
585 if let Some([p1]) = args.get(0..1) {
586 let fd = p1.to_i32();
587
588 Ok(to_wasm_return(p::fd_datasync(
589 data,
590 &mut mem as &mut Memory,
591 fd,
592 )))
593 } else {
594 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
595 }
596}
597
598fn fd_tell(
599 data: &mut WasiCtx,
600 _inst: &mut Instance,
601 frame: &mut CallingFrame,
602 args: Vec<WasmValue>,
603) -> Result<Vec<WasmValue>, CoreError> {
604 let mut mem = frame
605 .memory_mut(0)
606 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
607
608 if let Some([p1, p2]) = args.get(0..2) {
609 let fd = p1.to_i32();
610 let offset = p2.to_i32() as usize;
611
612 Ok(to_wasm_return(p::fd_tell(
613 data,
614 &mut mem as &mut Memory,
615 fd,
616 WasmPtr::from(offset),
617 )))
618 } else {
619 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
620 }
621}
622
623fn fd_fdstat_get(
624 data: &mut WasiCtx,
625 _inst: &mut Instance,
626 frame: &mut CallingFrame,
627 args: Vec<WasmValue>,
628) -> Result<Vec<WasmValue>, CoreError> {
629 let mut mem = frame
630 .memory_mut(0)
631 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
632
633 if let Some([p1, p2]) = args.get(0..2) {
634 let fd = p1.to_i32();
635 let buf_ptr = p2.to_i32() as usize;
636
637 Ok(to_wasm_return(p::fd_fdstat_get(
638 data,
639 &mut mem as &mut Memory,
640 fd,
641 WasmPtr::from(buf_ptr),
642 )))
643 } else {
644 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
645 }
646}
647
648fn fd_fdstat_set_flags(
649 data: &mut WasiCtx,
650 _inst: &mut Instance,
651 frame: &mut CallingFrame,
652 args: Vec<WasmValue>,
653) -> Result<Vec<WasmValue>, CoreError> {
654 let mut mem = frame
655 .memory_mut(0)
656 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
657
658 if let Some([p1, p2]) = args.get(0..2) {
659 let fd = p1.to_i32();
660 let flags = p2.to_i32() as u16;
661
662 Ok(to_wasm_return(p::fd_fdstat_set_flags(
663 data,
664 &mut mem as &mut Memory,
665 fd,
666 flags,
667 )))
668 } else {
669 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
670 }
671}
672
673fn fd_fdstat_set_rights(
674 data: &mut WasiCtx,
675 _inst: &mut Instance,
676 frame: &mut CallingFrame,
677 args: Vec<WasmValue>,
678) -> Result<Vec<WasmValue>, CoreError> {
679 let mut mem = frame
680 .memory_mut(0)
681 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
682
683 if let Some([p1, p2, p3]) = args.get(0..3) {
684 let fd = p1.to_i32();
685 let fs_rights_base = p2.to_i64() as u64;
686 let fs_rights_inheriting = p3.to_i64() as u64;
687
688 Ok(to_wasm_return(p::fd_fdstat_set_rights(
689 data,
690 &mut mem as &mut Memory,
691 fd,
692 fs_rights_base,
693 fs_rights_inheriting,
694 )))
695 } else {
696 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
697 }
698}
699
700fn fd_filestat_get(
701 data: &mut WasiCtx,
702 _inst: &mut Instance,
703 frame: &mut CallingFrame,
704 args: Vec<WasmValue>,
705) -> Result<Vec<WasmValue>, CoreError> {
706 let mut mem = frame
707 .memory_mut(0)
708 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
709
710 if let Some([p1, p2]) = args.get(0..2) {
711 let fd = p1.to_i32();
712 let buf = p2.to_i32() as usize;
713
714 Ok(to_wasm_return(p::fd_filestat_get(
715 data,
716 &mut mem as &mut Memory,
717 fd,
718 WasmPtr::from(buf),
719 )))
720 } else {
721 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
722 }
723}
724
725fn fd_filestat_set_size(
726 data: &mut WasiCtx,
727 _inst: &mut Instance,
728 frame: &mut CallingFrame,
729 args: Vec<WasmValue>,
730) -> Result<Vec<WasmValue>, CoreError> {
731 let mut mem = frame
732 .memory_mut(0)
733 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
734
735 if let Some([p1, p2]) = args.get(0..2) {
736 let fd = p1.to_i32();
737 let buf = p2.to_i32() as usize;
738
739 Ok(to_wasm_return(p::fd_filestat_get(
740 data,
741 &mut mem as &mut Memory,
742 fd,
743 WasmPtr::from(buf),
744 )))
745 } else {
746 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
747 }
748}
749
750fn fd_filestat_set_times(
751 data: &mut WasiCtx,
752 _inst: &mut Instance,
753 frame: &mut CallingFrame,
754 args: Vec<WasmValue>,
755) -> Result<Vec<WasmValue>, CoreError> {
756 let mut mem = frame
757 .memory_mut(0)
758 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
759
760 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
761 let fd = p1.to_i32();
762 let st_atim = p2.to_i64() as u64;
763 let st_mtim = p3.to_i64() as u64;
764 let fst_flags = p4.to_i32() as u16;
765
766 Ok(to_wasm_return(p::fd_filestat_set_times(
767 data,
768 &mut mem as &mut Memory,
769 fd,
770 st_atim,
771 st_mtim,
772 fst_flags,
773 )))
774 } else {
775 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
776 }
777}
778
779fn fd_read(
780 data: &mut WasiCtx,
781 _inst: &mut Instance,
782 frame: &mut CallingFrame,
783 args: Vec<WasmValue>,
784) -> Result<Vec<WasmValue>, CoreError> {
785 let mut mem = frame
786 .memory_mut(0)
787 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
788
789 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
790 let fd = p1.to_i32();
791 let iovs = p2.to_i32() as usize;
792 let iovs_len = p3.to_i32() as u32;
793 let nread = p4.to_i32() as usize;
794
795 Ok(to_wasm_return(p::fd_read(
796 data,
797 &mut mem as &mut Memory,
798 fd,
799 WasmPtr::from(iovs),
800 iovs_len,
801 WasmPtr::from(nread),
802 )))
803 } else {
804 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
805 }
806}
807
808fn fd_pread(
809 data: &mut WasiCtx,
810 _inst: &mut Instance,
811 frame: &mut CallingFrame,
812 args: Vec<WasmValue>,
813) -> Result<Vec<WasmValue>, CoreError> {
814 let mut mem = frame
815 .memory_mut(0)
816 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
817
818 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
819 let fd = p1.to_i32();
820 let iovs = p2.to_i32() as usize;
821 let iovs_len = p3.to_i32() as u32;
822 let offset = p4.to_i64() as u64;
823 let nread = p5.to_i32() as usize;
824
825 Ok(to_wasm_return(p::fd_pread(
826 data,
827 &mut mem as &mut Memory,
828 fd,
829 WasmPtr::from(iovs),
830 iovs_len,
831 offset,
832 WasmPtr::from(nread),
833 )))
834 } else {
835 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
836 }
837}
838
839fn fd_write(
840 data: &mut WasiCtx,
841 _inst: &mut Instance,
842 frame: &mut CallingFrame,
843 args: Vec<WasmValue>,
844) -> Result<Vec<WasmValue>, CoreError> {
845 let mut mem = frame
846 .memory_mut(0)
847 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
848
849 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
850 let fd = p1.to_i32();
851 let iovs = p2.to_i32() as usize;
852 let iovs_len = p3.to_i32() as u32;
853 let nwritten = p4.to_i32() as usize;
854
855 Ok(to_wasm_return(p::fd_write(
856 data,
857 &mut mem as &mut Memory,
858 fd,
859 WasmPtr::from(iovs),
860 iovs_len,
861 WasmPtr::from(nwritten),
862 )))
863 } else {
864 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
865 }
866}
867
868fn fd_pwrite(
869 data: &mut WasiCtx,
870 _inst: &mut Instance,
871 frame: &mut CallingFrame,
872 args: Vec<WasmValue>,
873) -> Result<Vec<WasmValue>, CoreError> {
874 let mut mem = frame
875 .memory_mut(0)
876 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
877
878 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
879 let fd = p1.to_i32();
880 let iovs = p2.to_i32() as usize;
881 let iovs_len = p3.to_i32() as u32;
882 let offset = p4.to_i64() as u64;
883 let nwritten = p5.to_i32() as usize;
884
885 Ok(to_wasm_return(p::fd_pwrite(
886 data,
887 &mut mem as &mut Memory,
888 fd,
889 WasmPtr::from(iovs),
890 iovs_len,
891 offset,
892 WasmPtr::from(nwritten),
893 )))
894 } else {
895 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
896 }
897}
898
899fn fd_readdir(
900 data: &mut WasiCtx,
901 _inst: &mut Instance,
902 frame: &mut CallingFrame,
903 args: Vec<WasmValue>,
904) -> Result<Vec<WasmValue>, CoreError> {
905 let mut mem = frame
906 .memory_mut(0)
907 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
908
909 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
910 let fd = p1.to_i32();
911 let buf = p2.to_i32() as usize;
912 let buf_len = p3.to_i32() as u32;
913 let cookie = p4.to_i64() as u64;
914 let bufused_ptr = p5.to_i32() as usize;
915
916 Ok(to_wasm_return(p::fd_readdir(
917 data,
918 &mut mem as &mut Memory,
919 fd,
920 WasmPtr::from(buf),
921 buf_len,
922 cookie,
923 WasmPtr::from(bufused_ptr),
924 )))
925 } else {
926 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
927 }
928}
929
930fn path_create_directory(
931 data: &mut WasiCtx,
932 _inst: &mut Instance,
933 frame: &mut CallingFrame,
934 args: Vec<WasmValue>,
935) -> Result<Vec<WasmValue>, CoreError> {
936 let mem = frame
937 .memory_mut(0)
938 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
939
940 if let Some([p1, p2, p3]) = args.get(0..3) {
941 let dirfd = p1.to_i32();
942 let path_ptr = p2.to_i32() as usize;
943 let path_len = p3.to_i32() as u32;
944
945 Ok(to_wasm_return(p::path_create_directory(
946 data,
947 &mem as &Memory,
948 dirfd,
949 WasmPtr::from(path_ptr),
950 path_len,
951 )))
952 } else {
953 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
954 }
955}
956
957fn path_filestat_get(
958 data: &mut WasiCtx,
959 _inst: &mut Instance,
960 frame: &mut CallingFrame,
961 args: Vec<WasmValue>,
962) -> Result<Vec<WasmValue>, CoreError> {
963 let mut mem = frame
964 .memory_mut(0)
965 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
966
967 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
968 let fd = p1.to_i32();
969 let flags = p2.to_i32() as u32;
970 let path_ptr = p3.to_i32() as usize;
971 let path_len = p4.to_i32() as u32;
972 let file_stat_ptr = p5.to_i32() as usize;
973
974 Ok(to_wasm_return(p::path_filestat_get(
975 data,
976 &mut mem as &mut Memory,
977 fd,
978 flags,
979 WasmPtr::from(path_ptr),
980 path_len,
981 WasmPtr::from(file_stat_ptr),
982 )))
983 } else {
984 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
985 }
986}
987
988fn path_filestat_set_times(
989 _data: &mut WasiCtx,
990 _inst: &mut Instance,
991 _frame: &mut CallingFrame,
992 _args: Vec<WasmValue>,
993) -> Result<Vec<WasmValue>, CoreError> {
994 Ok(vec![WasmValue::from_i32(
995 Errno::__WASI_ERRNO_NOSYS.0 as i32,
996 )])
997}
998
999fn path_link(
1000 _data: &mut WasiCtx,
1001 _inst: &mut Instance,
1002 _frame: &mut CallingFrame,
1003 _args: Vec<WasmValue>,
1004) -> Result<Vec<WasmValue>, CoreError> {
1005 Ok(vec![WasmValue::from_i32(
1006 Errno::__WASI_ERRNO_NOSYS.0 as i32,
1007 )])
1008}
1009
1010fn path_open(
1011 data: &mut WasiCtx,
1012 _inst: &mut Instance,
1013 frame: &mut CallingFrame,
1014 args: Vec<WasmValue>,
1015) -> Result<Vec<WasmValue>, CoreError> {
1016 let mut mem = frame
1017 .memory_mut(0)
1018 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1019
1020 if let Some([p1, p2, p3, p4, p5, p6, p7, p8, p9]) = args.get(0..9) {
1021 let dirfd = p1.to_i32();
1022 let dirflags = p2.to_i32() as u32;
1023 let path = p3.to_i32() as usize;
1024 let path_len = p4.to_i32() as u32;
1025 let o_flags = p5.to_i32() as u16;
1026 let fs_rights_base = p6.to_i64() as u64;
1027 let fs_rights_inheriting = p7.to_i64() as u64;
1028 let fs_flags = p8.to_i32() as u16;
1029 let fd_ptr = p9.to_i32() as usize;
1030
1031 Ok(to_wasm_return(p::path_open(
1032 data,
1033 &mut mem as &mut Memory,
1034 dirfd,
1035 dirflags,
1036 WasmPtr::from(path),
1037 path_len,
1038 o_flags,
1039 fs_rights_base,
1040 fs_rights_inheriting,
1041 fs_flags,
1042 WasmPtr::from(fd_ptr),
1043 )))
1044 } else {
1045 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1046 }
1047}
1048
1049fn path_readlink(
1050 _data: &mut WasiCtx,
1051 _inst: &mut Instance,
1052 _frame: &mut CallingFrame,
1053 _args: Vec<WasmValue>,
1054) -> Result<Vec<WasmValue>, CoreError> {
1055 Ok(vec![WasmValue::from_i32(
1056 Errno::__WASI_ERRNO_NOSYS.0 as i32,
1057 )])
1058}
1059
1060fn path_remove_directory(
1061 data: &mut WasiCtx,
1062 _inst: &mut Instance,
1063 frame: &mut CallingFrame,
1064 args: Vec<WasmValue>,
1065) -> Result<Vec<WasmValue>, CoreError> {
1066 let mem = frame
1067 .memory_mut(0)
1068 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1069
1070 if let Some([p1, p2, p3]) = args.get(0..3) {
1071 let fd = p1.to_i32();
1072 let path_ptr = p2.to_i32() as usize;
1073 let path_len = p3.to_i32() as u32;
1074
1075 Ok(to_wasm_return(p::path_remove_directory(
1076 data,
1077 &mem as &Memory,
1078 fd,
1079 WasmPtr::from(path_ptr),
1080 path_len,
1081 )))
1082 } else {
1083 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1084 }
1085}
1086
1087fn path_rename(
1088 data: &mut WasiCtx,
1089 _inst: &mut Instance,
1090 frame: &mut CallingFrame,
1091 args: Vec<WasmValue>,
1092) -> Result<Vec<WasmValue>, CoreError> {
1093 let mem = frame
1094 .memory_mut(0)
1095 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1096
1097 if let Some([p1, p2, p3, p4, p5, p6]) = args.get(0..6) {
1098 let old_fd = p1.to_i32();
1099 let old_path = p2.to_i32() as usize;
1100 let old_path_len = p3.to_i32() as u32;
1101 let new_fd = p4.to_i32();
1102 let new_path = p5.to_i32() as usize;
1103 let new_path_len = p6.to_i32() as u32;
1104
1105 Ok(to_wasm_return(p::path_rename(
1106 data,
1107 &mem as &Memory,
1108 old_fd,
1109 WasmPtr::from(old_path),
1110 old_path_len,
1111 new_fd,
1112 WasmPtr::from(new_path),
1113 new_path_len,
1114 )))
1115 } else {
1116 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1117 }
1118}
1119
1120fn path_symlink(
1121 _data: &mut WasiCtx,
1122 _inst: &mut Instance,
1123 _frame: &mut CallingFrame,
1124 _args: Vec<WasmValue>,
1125) -> Result<Vec<WasmValue>, CoreError> {
1126 Ok(vec![WasmValue::from_i32(
1127 Errno::__WASI_ERRNO_NOSYS.0 as i32,
1128 )])
1129}
1130
1131fn path_unlink_file(
1132 data: &mut WasiCtx,
1133 _inst: &mut Instance,
1134 frame: &mut CallingFrame,
1135 args: Vec<WasmValue>,
1136) -> Result<Vec<WasmValue>, CoreError> {
1137 let mem = frame
1138 .memory_mut(0)
1139 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1140
1141 if let Some([p1, p2, p3]) = args.get(0..3) {
1142 let fd = p1.to_i32();
1143 let path_ptr = p2.to_i32() as usize;
1144 let path_len = p3.to_i32() as u32;
1145
1146 Ok(to_wasm_return(p::path_unlink_file(
1147 data,
1148 &mem as &Memory,
1149 fd,
1150 WasmPtr::from(path_ptr),
1151 path_len,
1152 )))
1153 } else {
1154 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1155 }
1156}
1157
1158fn proc_exit(
1159 data: &mut WasiCtx,
1160 _inst: &mut Instance,
1161 frame: &mut CallingFrame,
1162 args: Vec<WasmValue>,
1163) -> Result<Vec<WasmValue>, CoreError> {
1164 let mut mem = frame
1165 .memory_mut(0)
1166 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1167
1168 if let Some([p1]) = args.get(0..1) {
1169 let code = p1.to_i32() as u32;
1170 p::proc_exit(data, &mut mem as &mut Memory, code);
1171 Err(CoreError::Common(CoreCommonError::Terminated))
1172 } else {
1173 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1174 }
1175}
1176
1177fn proc_raise(
1178 _data: &mut WasiCtx,
1179 _inst: &mut Instance,
1180 _frame: &mut CallingFrame,
1181 _args: Vec<WasmValue>,
1182) -> Result<Vec<WasmValue>, CoreError> {
1183 Ok(vec![WasmValue::from_i32(
1184 Errno::__WASI_ERRNO_NOSYS.0 as i32,
1185 )])
1186}
1187
1188fn sched_yield(
1191 _data: &mut WasiCtx,
1192 _inst: &mut Instance,
1193 _frame: &mut CallingFrame,
1194 _args: Vec<WasmValue>,
1195) -> Result<Vec<WasmValue>, CoreError> {
1196 Ok(vec![WasmValue::from_i32(
1197 Errno::__WASI_ERRNO_NOSYS.0 as i32,
1198 )])
1199}
1200
1201fn sock_open(
1204 data: &mut WasiCtx,
1205 _inst: &mut Instance,
1206 frame: &mut CallingFrame,
1207 args: Vec<WasmValue>,
1208) -> Result<Vec<WasmValue>, CoreError> {
1209 let mut mem = frame
1210 .memory_mut(0)
1211 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1212
1213 if let Some([p1, p2, p3]) = args.get(0..3) {
1214 let af = p1.to_i32() as u8;
1215 let ty = p2.to_i32() as u8;
1216 let ro_fd_ptr = p3.to_i32() as usize;
1217
1218 Ok(to_wasm_return(p::async_socket::sock_open(
1219 data,
1220 &mut mem as &mut Memory,
1221 af,
1222 ty,
1223 WasmPtr::from(ro_fd_ptr),
1224 )))
1225 } else {
1226 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1227 }
1228}
1229
1230fn sock_bind(
1231 data: &mut WasiCtx,
1232 _inst: &mut Instance,
1233 frame: &mut CallingFrame,
1234 args: Vec<WasmValue>,
1235) -> Result<Vec<WasmValue>, CoreError> {
1236 let mem = frame
1237 .memory_mut(0)
1238 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1239
1240 if let Some([p1, p2, p3]) = args.get(0..3) {
1241 let fd = p1.to_i32();
1242 let addr_ptr = p2.to_i32() as usize;
1243 let port = p3.to_i32() as u32;
1244 Ok(to_wasm_return(p::async_socket::sock_bind(
1245 data,
1246 &mem as &Memory,
1247 fd,
1248 WasmPtr::from(addr_ptr),
1249 port,
1250 )))
1251 } else {
1252 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1253 }
1254}
1255
1256fn sock_listen(
1257 data: &mut WasiCtx,
1258 _inst: &mut Instance,
1259 frame: &mut CallingFrame,
1260 args: Vec<WasmValue>,
1261) -> Result<Vec<WasmValue>, CoreError> {
1262 let mut mem = frame
1263 .memory_mut(0)
1264 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1265
1266 if let Some([p1, p2]) = args.get(0..2) {
1267 let fd = p1.to_i32();
1268 let backlog = p2.to_i32() as u32;
1269
1270 Ok(to_wasm_return(p::async_socket::sock_listen(
1271 data,
1272 &mut mem as &mut Memory,
1273 fd,
1274 backlog,
1275 )))
1276 } else {
1277 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1278 }
1279}
1280
1281fn sock_accept<'data, 'inst, 'frame, 'fut>(
1282 data: &'data mut WasiCtx,
1283 _inst: &'inst mut AsyncInstance,
1284 frame: &'frame mut CallingFrame,
1285 args: Vec<WasmValue>,
1286) -> Box<dyn Future<Output = Result<Vec<WasmValue>, CoreError>> + Send + 'fut>
1287where
1288 'data: 'fut,
1289 'frame: 'fut,
1290 'inst: 'fut,
1291{
1292 Box::new(async move {
1293 let mut mem = frame
1294 .memory_mut(0)
1295 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1296
1297 if let Some([p1, p2]) = args.get(0..2) {
1298 let fd = p1.to_i32();
1299 let ro_fd_ptr = p2.to_i32() as usize;
1300
1301 Ok(to_wasm_return(
1302 p::async_socket::sock_accept(
1303 data,
1304 &mut mem as &mut Memory,
1305 fd,
1306 WasmPtr::from(ro_fd_ptr),
1307 )
1308 .await,
1309 ))
1310 } else {
1311 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1312 }
1313 })
1314}
1315
1316async fn sock_connect(
1317 data: &mut WasiCtx,
1318 _inst: &mut AsyncInstance,
1319 frame: &mut CallingFrame,
1320 args: Vec<WasmValue>,
1321) -> Result<Vec<WasmValue>, CoreError> {
1322 let mem = frame
1323 .memory_mut(0)
1324 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1325
1326 if let Some([p1, p2, p3]) = args.get(0..3) {
1327 let fd = p1.to_i32();
1328 let addr_ptr = p2.to_i32() as usize;
1329 let port = p3.to_i32() as u32;
1330
1331 Ok(to_wasm_return(
1332 p::async_socket::sock_connect(data, &mem as &Memory, fd, WasmPtr::from(addr_ptr), port)
1333 .await,
1334 ))
1335 } else {
1336 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1337 }
1338}
1339
1340async fn sock_recv(
1341 data: &mut WasiCtx,
1342 _inst: &mut AsyncInstance,
1343 frame: &mut CallingFrame,
1344 args: Vec<WasmValue>,
1345) -> Result<Vec<WasmValue>, CoreError> {
1346 let mut mem = frame
1347 .memory_mut(0)
1348 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1349
1350 if let Some([p1, p2, p3, p4, p5, p6]) = args.get(0..6) {
1351 let fd = p1.to_i32();
1352 let buf_ptr = p2.to_i32() as usize;
1353 let buf_len = p3.to_i32() as u32;
1354 let flags = p4.to_i32() as u16;
1355 let ro_data_len_ptr = p5.to_i32() as usize;
1356 let ro_flags_ptr = p6.to_i32() as usize;
1357
1358 Ok(to_wasm_return(
1359 p::async_socket::sock_recv(
1360 data,
1361 &mut mem as &mut Memory,
1362 fd,
1363 WasmPtr::from(buf_ptr),
1364 buf_len,
1365 flags,
1366 WasmPtr::from(ro_data_len_ptr),
1367 WasmPtr::from(ro_flags_ptr),
1368 )
1369 .await,
1370 ))
1371 } else {
1372 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1373 }
1374}
1375
1376async fn sock_recv_from(
1377 data: &mut WasiCtx,
1378 _inst: &mut AsyncInstance,
1379 frame: &mut CallingFrame,
1380 args: Vec<WasmValue>,
1381) -> Result<Vec<WasmValue>, CoreError> {
1382 let mut mem = frame
1383 .memory_mut(0)
1384 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1385
1386 if let Some([p1, p2, p3, p4, p5, p6, p7, p8]) = args.get(0..8) {
1387 let fd = p1.to_i32();
1388 let buf_ptr = p2.to_i32() as usize;
1389 let buf_len = p3.to_i32() as u32;
1390 let wasi_addr_ptr = p4.to_i32() as usize;
1391 let flags = p5.to_i32() as u16;
1392 let port_ptr = p6.to_i32() as usize;
1393 let ro_data_len_ptr = p7.to_i32() as usize;
1394 let ro_flags_ptr = p8.to_i32() as usize;
1395
1396 Ok(to_wasm_return(
1397 p::async_socket::sock_recv_from(
1398 data,
1399 &mut mem as &mut Memory,
1400 fd,
1401 WasmPtr::from(buf_ptr),
1402 buf_len,
1403 WasmPtr::from(wasi_addr_ptr),
1404 flags,
1405 WasmPtr::from(port_ptr),
1406 WasmPtr::from(ro_data_len_ptr),
1407 WasmPtr::from(ro_flags_ptr),
1408 )
1409 .await,
1410 ))
1411 } else {
1412 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1413 }
1414}
1415
1416async fn sock_send(
1417 data: &mut WasiCtx,
1418 _inst: &mut AsyncInstance,
1419 frame: &mut CallingFrame,
1420 args: Vec<WasmValue>,
1421) -> Result<Vec<WasmValue>, CoreError> {
1422 let mut mem = frame
1423 .memory_mut(0)
1424 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1425
1426 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
1427 let fd = p1.to_i32();
1428 let buf_ptr = p2.to_i32() as usize;
1429 let buf_len = p3.to_i32() as u32;
1430 let flags = p4.to_i32() as u16;
1431 let send_len_ptr = p5.to_i32() as usize;
1432
1433 Ok(to_wasm_return(
1434 p::async_socket::sock_send(
1435 data,
1436 &mut mem as &mut Memory,
1437 fd,
1438 WasmPtr::from(buf_ptr),
1439 buf_len,
1440 flags,
1441 WasmPtr::from(send_len_ptr),
1442 )
1443 .await,
1444 ))
1445 } else {
1446 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1447 }
1448}
1449
1450async fn sock_send_to(
1451 data: &mut WasiCtx,
1452 _inst: &mut AsyncInstance,
1453 frame: &mut CallingFrame,
1454 args: Vec<WasmValue>,
1455) -> Result<Vec<WasmValue>, CoreError> {
1456 let mut mem = frame
1457 .memory_mut(0)
1458 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1459
1460 if let Some([p1, p2, p3, p4, p5, p6, p7]) = args.get(0..7) {
1461 let fd = p1.to_i32();
1462 let buf_ptr = p2.to_i32() as usize;
1463 let buf_len = p3.to_i32() as u32;
1464 let wasi_addr_ptr = p4.to_i32() as usize;
1465 let port = p5.to_i32() as u32;
1466 let flags = p6.to_i32() as u16;
1467 let send_len_ptr = p7.to_i32() as usize;
1468
1469 Ok(to_wasm_return(
1470 p::async_socket::sock_send_to(
1471 data,
1472 &mut mem as &mut Memory,
1473 fd,
1474 WasmPtr::from(buf_ptr),
1475 buf_len,
1476 WasmPtr::from(wasi_addr_ptr),
1477 port,
1478 flags,
1479 WasmPtr::from(send_len_ptr),
1480 )
1481 .await,
1482 ))
1483 } else {
1484 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1485 }
1486}
1487
1488fn sock_shutdown(
1489 data: &mut WasiCtx,
1490 _inst: &mut Instance,
1491 frame: &mut CallingFrame,
1492 args: Vec<WasmValue>,
1493) -> Result<Vec<WasmValue>, CoreError> {
1494 let mut mem = frame
1495 .memory_mut(0)
1496 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1497
1498 if let Some([p1, p2]) = args.get(0..2) {
1499 let fd = p1.to_i32();
1500 let how = p2.to_i32() as u8;
1501 Ok(to_wasm_return(p::async_socket::sock_shutdown(
1502 data,
1503 &mut mem as &mut Memory,
1504 fd,
1505 how,
1506 )))
1507 } else {
1508 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1509 }
1510}
1511
1512fn sock_getpeeraddr(
1513 data: &mut WasiCtx,
1514 _inst: &mut Instance,
1515 frame: &mut CallingFrame,
1516 args: Vec<WasmValue>,
1517) -> Result<Vec<WasmValue>, CoreError> {
1518 let mut mem = frame
1519 .memory_mut(0)
1520 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1521
1522 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
1523 let fd = p1.to_i32();
1524 let wasi_addr_ptr = p2.to_i32() as usize;
1525 let addr_type = p3.to_i32() as usize;
1526 let port_ptr = p4.to_i32() as usize;
1527 Ok(to_wasm_return(p::async_socket::sock_getpeeraddr(
1528 data,
1529 &mut mem as &mut Memory,
1530 fd,
1531 WasmPtr::from(wasi_addr_ptr),
1532 WasmPtr::from(addr_type),
1533 WasmPtr::from(port_ptr),
1534 )))
1535 } else {
1536 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1537 }
1538}
1539
1540fn sock_getlocaladdr(
1541 data: &mut WasiCtx,
1542 _inst: &mut Instance,
1543 frame: &mut CallingFrame,
1544 args: Vec<WasmValue>,
1545) -> Result<Vec<WasmValue>, CoreError> {
1546 let mut mem = frame
1547 .memory_mut(0)
1548 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1549
1550 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
1551 let fd = p1.to_i32();
1552 let wasi_addr_ptr = p2.to_i32() as usize;
1553 let addr_type = p3.to_i32() as usize;
1554 let port_ptr = p4.to_i32() as usize;
1555 Ok(to_wasm_return(p::async_socket::sock_getlocaladdr(
1556 data,
1557 &mut mem as &mut Memory,
1558 fd,
1559 WasmPtr::from(wasi_addr_ptr),
1560 WasmPtr::from(addr_type),
1561 WasmPtr::from(port_ptr),
1562 )))
1563 } else {
1564 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1565 }
1566}
1567
1568fn sock_getsockopt(
1569 data: &mut WasiCtx,
1570 _inst: &mut Instance,
1571 frame: &mut CallingFrame,
1572 args: Vec<WasmValue>,
1573) -> Result<Vec<WasmValue>, CoreError> {
1574 let mut mem = frame
1575 .memory_mut(0)
1576 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1577
1578 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
1579 let fd = p1.to_i32();
1580 let level = p2.to_i32() as u32;
1581 let name = p3.to_i32() as u32;
1582 let flag = p4.to_i32() as usize;
1583 let flag_size_ptr = p5.to_i32() as usize;
1584 Ok(to_wasm_return(p::async_socket::sock_getsockopt(
1585 data,
1586 &mut mem as &mut Memory,
1587 fd,
1588 level,
1589 name,
1590 WasmPtr::from(flag),
1591 WasmPtr::from(flag_size_ptr),
1592 )))
1593 } else {
1594 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1595 }
1596}
1597
1598fn sock_setsockopt(
1599 data: &mut WasiCtx,
1600 _inst: &mut Instance,
1601 frame: &mut CallingFrame,
1602 args: Vec<WasmValue>,
1603) -> Result<Vec<WasmValue>, CoreError> {
1604 let mem = frame
1605 .memory_mut(0)
1606 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1607
1608 if let Some([p1, p2, p3, p4, p5]) = args.get(0..5) {
1609 let fd = p1.to_i32();
1610 let level = p2.to_i32() as u32;
1611 let name = p3.to_i32() as u32;
1612 let flag = p4.to_i32() as usize;
1613 let flag_size = p5.to_i32() as u32;
1614 Ok(to_wasm_return(p::async_socket::sock_setsockopt(
1615 data,
1616 &mem as &Memory,
1617 fd,
1618 level,
1619 name,
1620 WasmPtr::from(flag),
1621 flag_size,
1622 )))
1623 } else {
1624 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1625 }
1626}
1627
1628fn sock_getaddrinfo(
1629 data: &mut WasiCtx,
1630 _inst: &mut Instance,
1631 frame: &mut CallingFrame,
1632 args: Vec<WasmValue>,
1633) -> Result<Vec<WasmValue>, CoreError> {
1634 let mut mem = frame
1635 .memory_mut(0)
1636 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1637
1638 if let Some([p1, p2, p3, p4, p5, p6, p7, p8]) = args.get(0..8) {
1639 let node = p1.to_i32() as usize;
1640 let node_len = p2.to_i32() as u32;
1641 let server = p3.to_i32() as usize;
1642 let server_len = p4.to_i32() as u32;
1643 let hint = p5.to_i32() as usize;
1644 let res = p6.to_i32() as usize;
1645 let max_len = p7.to_i32() as u32;
1646 let res_len = p8.to_i32() as usize;
1647
1648 Ok(to_wasm_return(p::async_socket::addrinfo::sock_getaddrinfo(
1649 data,
1650 &mut mem as &mut Memory,
1651 WasmPtr::from(node),
1652 node_len,
1653 WasmPtr::from(server),
1654 server_len,
1655 WasmPtr::from(hint),
1656 WasmPtr::from(res),
1657 max_len,
1658 WasmPtr::from(res_len),
1659 )))
1660 } else {
1661 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1662 }
1663}
1664
1665async fn poll_oneoff(
1666 data: &mut WasiCtx,
1667 _inst: &mut AsyncInstance,
1668 frame: &mut CallingFrame,
1669 args: Vec<WasmValue>,
1670) -> Result<Vec<WasmValue>, CoreError> {
1671 let mut mem = frame
1672 .memory_mut(0)
1673 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1674
1675 if let Some([p1, p2, p3, p4]) = args.get(0..4) {
1676 let in_ptr = p1.to_i32() as usize;
1677 let out_ptr = p2.to_i32() as usize;
1678 let nsubscriptions = p3.to_i32() as u32;
1679 let revents_num_ptr = p4.to_i32() as usize;
1680
1681 Ok(to_wasm_return(
1682 p::async_poll::poll_oneoff(
1683 data,
1684 &mut mem as &mut Memory,
1685 WasmPtr::from(in_ptr),
1686 WasmPtr::from(out_ptr),
1687 nsubscriptions,
1688 WasmPtr::from(revents_num_ptr),
1689 )
1690 .await,
1691 ))
1692 } else {
1693 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1694 }
1695}
1696
1697async fn sock_lookup_ip(
1698 data: &mut WasiCtx,
1699 _inst: &mut AsyncInstance,
1700 frame: &mut CallingFrame,
1701 args: Vec<WasmValue>,
1702) -> Result<Vec<WasmValue>, CoreError> {
1703 let mut mem = frame
1704 .memory_mut(0)
1705 .ok_or(CoreError::Execution(CoreExecutionError::MemoryOutOfBounds))?;
1706
1707 if let Some([p1, p2, p3, p4, p5, p6]) = args.get(0..6) {
1708 let host_name_ptr = p1.to_i32() as usize;
1709 let host_name_len = p2.to_i32() as u32;
1710 let lookup_type = p3.to_i32() as u8;
1711 let addr_buf = p4.to_i32() as usize;
1712 let addr_buf_max_len = p5.to_i32() as u32;
1713 let raddr_num_ptr = p6.to_i32() as usize;
1714 Ok(to_wasm_return(
1715 p::async_socket::sock_lookup_ip(
1716 data,
1717 &mut mem as &mut Memory,
1718 WasmPtr::from(host_name_ptr),
1719 host_name_len,
1720 lookup_type,
1721 WasmPtr::from(addr_buf),
1722 addr_buf_max_len,
1723 WasmPtr::from(raddr_num_ptr),
1724 )
1725 .await,
1726 ))
1727 } else {
1728 Err(CoreError::Execution(CoreExecutionError::FuncSigMismatch))
1729 }
1730}
1731
1732#[inline]
1733fn box_future<
1734 'data,
1735 'inst,
1736 'frame,
1737 'fut,
1738 Data: Send,
1739 Fut: Future<Output = Result<Vec<WasmValue>, CoreError>> + Send + 'fut,
1740 F: FnOnce(
1741 &'data mut Data,
1742 &'inst mut AsyncInstance,
1743 &'frame mut CallingFrame,
1744 Vec<WasmValue>,
1745 ) -> Fut,
1746>(
1747 data: &'data mut Data,
1748 inst: &'inst mut AsyncInstance,
1749 frame: &'frame mut CallingFrame,
1750 args: Vec<WasmValue>,
1751) -> Box<dyn Future<Output = Result<Vec<WasmValue>, CoreError>> + Send + 'fut>
1752where
1753 'data: 'fut,
1754 'inst: 'fut,
1755 'frame: 'fut,
1756{
1757 let f: F = unsafe { std::mem::zeroed() };
1758 Box::new(f(data, inst, frame, args))
1759}
1760
1761#[allow(clippy::complexity)]
1762fn wrap_future<
1763 'data,
1764 'inst,
1765 'frame,
1766 'fut,
1767 Data: Send + 'data,
1768 Fut: Future<Output = Result<Vec<WasmValue>, CoreError>> + Send + 'fut,
1769 F: FnOnce(
1770 &'data mut Data,
1771 &'inst mut AsyncInstance,
1772 &'frame mut CallingFrame,
1773 Vec<WasmValue>,
1774 ) -> Fut,
1775>(
1776 _f: F,
1777) -> fn(
1778 data: &'data mut Data,
1779 inst: &'inst mut AsyncInstance,
1780 frame: &'frame mut CallingFrame,
1781 args: Vec<WasmValue>,
1782) -> Box<dyn Future<Output = Result<Vec<WasmValue>, CoreError>> + Send + 'fut>
1783where
1784 'data: 'fut,
1785 'inst: 'fut,
1786 'frame: 'fut,
1787{
1788 box_future::<Data, Fut, F>
1789}
1790
1791enum WasiFunc<'data, 'inst, 'frame, 'fut, T: Sized>
1792where
1793 'data: 'fut,
1794 'inst: 'fut,
1795 'frame: 'fut,
1796{
1797 SyncFn(String, (Vec<ValType>, Vec<ValType>), SyncFn<T>),
1798 AsyncFn(
1799 String,
1800 (Vec<ValType>, Vec<ValType>),
1801 AsyncFn<'data, 'inst, 'frame, 'fut, T>,
1802 ),
1803}
1804
1805fn wasi_impls<'data, 'inst, 'frame, 'fut>() -> Vec<WasiFunc<'data, 'inst, 'frame, 'fut, WasiCtx>> {
1806 macro_rules! sync_fn {
1807 ($name:expr, $ty:expr, $f:ident) => {
1808 WasiFunc::SyncFn($name.into(), $ty, $f)
1809 };
1810 }
1811 macro_rules! async_fn {
1812 ($name:expr, $ty:expr, $f:expr) => {
1813 WasiFunc::AsyncFn($name.into(), $ty, $f)
1814 };
1815 }
1816 vec![
1817 sync_fn!(
1818 "args_get",
1819 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1820 args_get
1821 ),
1822 sync_fn!(
1823 "args_sizes_get",
1824 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1825 args_sizes_get
1826 ),
1827 sync_fn!(
1828 "environ_get",
1829 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1830 environ_get
1831 ),
1832 sync_fn!(
1833 "environ_sizes_get",
1834 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1835 environ_sizes_get
1836 ),
1837 sync_fn!(
1838 "clock_res_get",
1839 (vec![ValType::I32, ValType::I64], vec![ValType::I32]),
1840 clock_res_get
1841 ),
1842 sync_fn!(
1843 "clock_time_get",
1844 (
1845 vec![ValType::I32, ValType::I64, ValType::I32],
1846 vec![ValType::I32],
1847 ),
1848 clock_time_get
1849 ),
1850 sync_fn!(
1851 "random_get",
1852 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1853 random_get
1854 ),
1855 sync_fn!(
1856 "fd_prestat_get",
1857 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1858 fd_prestat_get
1859 ),
1860 sync_fn!(
1861 "fd_prestat_dir_name",
1862 (
1863 vec![ValType::I32, ValType::I32, ValType::I32],
1864 vec![ValType::I32],
1865 ),
1866 fd_prestat_dir_name
1867 ),
1868 sync_fn!(
1869 "fd_renumber",
1870 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1871 fd_renumber
1872 ),
1873 sync_fn!(
1874 "fd_advise",
1875 (
1876 vec![ValType::I32, ValType::I64, ValType::I64, ValType::I32],
1877 vec![ValType::I32],
1878 ),
1879 fd_advise
1880 ),
1881 sync_fn!(
1882 "fd_allocate",
1883 (
1884 vec![ValType::I32, ValType::I64, ValType::I64],
1885 vec![ValType::I32],
1886 ),
1887 fd_allocate
1888 ),
1889 sync_fn!(
1890 "fd_close",
1891 (vec![ValType::I32], vec![ValType::I32]),
1892 fd_close
1893 ),
1894 sync_fn!(
1895 "fd_seek",
1896 (
1897 vec![ValType::I32, ValType::I64, ValType::I32, ValType::I32],
1898 vec![ValType::I32],
1899 ),
1900 fd_seek
1901 ),
1902 sync_fn!("fd_sync", (vec![ValType::I32], vec![ValType::I32]), fd_sync),
1903 sync_fn!(
1904 "fd_datasync",
1905 (vec![ValType::I32], vec![ValType::I32]),
1906 fd_datasync
1907 ),
1908 sync_fn!(
1909 "fd_tell",
1910 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1911 fd_tell
1912 ),
1913 sync_fn!(
1914 "fd_fdstat_get",
1915 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1916 fd_fdstat_get
1917 ),
1918 sync_fn!(
1919 "fd_fdstat_set_flags",
1920 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1921 fd_fdstat_set_flags
1922 ),
1923 sync_fn!(
1924 "fd_fdstat_set_rights",
1925 (
1926 vec![ValType::I32, ValType::I64, ValType::I64],
1927 vec![ValType::I32],
1928 ),
1929 fd_fdstat_set_rights
1930 ),
1931 sync_fn!(
1932 "fd_filestat_get",
1933 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1934 fd_filestat_get
1935 ),
1936 sync_fn!(
1937 "fd_filestat_set_size",
1938 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
1939 fd_filestat_set_size
1940 ),
1941 sync_fn!(
1942 "fd_filestat_set_times",
1943 (
1944 vec![ValType::I32, ValType::I64, ValType::I64, ValType::I32],
1945 vec![ValType::I32],
1946 ),
1947 fd_filestat_set_times
1948 ),
1949 sync_fn!(
1950 "fd_read",
1951 (
1952 vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
1953 vec![ValType::I32],
1954 ),
1955 fd_read
1956 ),
1957 sync_fn!(
1958 "fd_pread",
1959 (
1960 vec![
1961 ValType::I32,
1962 ValType::I32,
1963 ValType::I32,
1964 ValType::I64,
1965 ValType::I32,
1966 ],
1967 vec![ValType::I32],
1968 ),
1969 fd_pread
1970 ),
1971 sync_fn!(
1972 "fd_write",
1973 (
1974 vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
1975 vec![ValType::I32],
1976 ),
1977 fd_write
1978 ),
1979 sync_fn!(
1980 "fd_pwrite",
1981 (
1982 vec![
1983 ValType::I32,
1984 ValType::I32,
1985 ValType::I32,
1986 ValType::I64,
1987 ValType::I32,
1988 ],
1989 vec![ValType::I32],
1990 ),
1991 fd_pwrite
1992 ),
1993 sync_fn!(
1994 "fd_readdir",
1995 (
1996 vec![
1997 ValType::I32,
1998 ValType::I32,
1999 ValType::I32,
2000 ValType::I64,
2001 ValType::I32,
2002 ],
2003 vec![ValType::I32],
2004 ),
2005 fd_readdir
2006 ),
2007 sync_fn!(
2008 "path_create_directory",
2009 (
2010 vec![ValType::I32, ValType::I32, ValType::I32],
2011 vec![ValType::I32],
2012 ),
2013 path_create_directory
2014 ),
2015 sync_fn!(
2016 "path_filestat_get",
2017 (
2018 vec![
2019 ValType::I32,
2020 ValType::I32,
2021 ValType::I32,
2022 ValType::I32,
2023 ValType::I32,
2024 ],
2025 vec![ValType::I32],
2026 ),
2027 path_filestat_get
2028 ),
2029 sync_fn!(
2030 "path_filestat_set_times",
2031 (
2032 vec![
2033 ValType::I32,
2034 ValType::I32,
2035 ValType::I32,
2036 ValType::I32,
2037 ValType::I64,
2038 ValType::I64,
2039 ValType::I32,
2040 ],
2041 vec![ValType::I32],
2042 ),
2043 path_filestat_set_times
2044 ),
2045 sync_fn!(
2046 "path_link",
2047 (
2048 vec![
2049 ValType::I32,
2050 ValType::I32,
2051 ValType::I32,
2052 ValType::I32,
2053 ValType::I32,
2054 ValType::I32,
2055 ValType::I32,
2056 ],
2057 vec![ValType::I32],
2058 ),
2059 path_link
2060 ),
2061 sync_fn!(
2062 "path_open",
2063 (
2064 vec![
2065 ValType::I32,
2066 ValType::I32,
2067 ValType::I32,
2068 ValType::I32,
2069 ValType::I32,
2070 ValType::I64,
2071 ValType::I64,
2072 ValType::I32,
2073 ValType::I32,
2074 ],
2075 vec![ValType::I32],
2076 ),
2077 path_open
2078 ),
2079 sync_fn!(
2080 "path_readlink",
2081 (
2082 vec![
2083 ValType::I32,
2084 ValType::I32,
2085 ValType::I32,
2086 ValType::I32,
2087 ValType::I32,
2088 ValType::I32,
2089 ],
2090 vec![ValType::I32],
2091 ),
2092 path_readlink
2093 ),
2094 sync_fn!(
2095 "path_remove_directory",
2096 (
2097 vec![ValType::I32, ValType::I32, ValType::I32],
2098 vec![ValType::I32],
2099 ),
2100 path_remove_directory
2101 ),
2102 sync_fn!(
2103 "path_rename",
2104 (
2105 vec![
2106 ValType::I32,
2107 ValType::I32,
2108 ValType::I32,
2109 ValType::I32,
2110 ValType::I32,
2111 ValType::I32,
2112 ],
2113 vec![ValType::I32],
2114 ),
2115 path_rename
2116 ),
2117 sync_fn!(
2118 "path_symlink",
2119 (
2120 vec![
2121 ValType::I32,
2122 ValType::I32,
2123 ValType::I32,
2124 ValType::I32,
2125 ValType::I32,
2126 ],
2127 vec![ValType::I32],
2128 ),
2129 path_symlink
2130 ),
2131 sync_fn!(
2132 "path_unlink_file",
2133 (
2134 vec![ValType::I32, ValType::I32, ValType::I32],
2135 vec![ValType::I32],
2136 ),
2137 path_unlink_file
2138 ),
2139 sync_fn!("proc_exit", (vec![ValType::I32], vec![]), proc_exit),
2140 sync_fn!(
2141 "proc_raise",
2142 (vec![ValType::I32], vec![ValType::I32]),
2143 proc_raise
2144 ),
2145 sync_fn!("sched_yield", (vec![], vec![ValType::I32]), sched_yield),
2146 sync_fn!(
2147 "sock_open",
2148 (
2149 vec![ValType::I32, ValType::I32, ValType::I32],
2150 vec![ValType::I32],
2151 ),
2152 sock_open
2153 ),
2154 sync_fn!(
2155 "sock_bind",
2156 (
2157 vec![ValType::I32, ValType::I32, ValType::I32],
2158 vec![ValType::I32],
2159 ),
2160 sock_bind
2161 ),
2162 sync_fn!(
2163 "sock_listen",
2164 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
2165 sock_listen
2166 ),
2167 async_fn!(
2168 "sock_accept",
2169 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
2170 sock_accept
2171 ),
2172 async_fn!(
2173 "sock_connect",
2174 (
2175 vec![ValType::I32, ValType::I32, ValType::I32],
2176 vec![ValType::I32],
2177 ),
2178 wrap_future(sock_connect)
2179 ),
2180 async_fn!(
2181 "sock_recv",
2182 (
2183 vec![
2184 ValType::I32,
2185 ValType::I32,
2186 ValType::I32,
2187 ValType::I32,
2188 ValType::I32,
2189 ValType::I32,
2190 ],
2191 vec![ValType::I32],
2192 ),
2193 wrap_future(sock_recv)
2194 ),
2195 async_fn!(
2196 "sock_recv_from",
2197 (
2198 vec![
2199 ValType::I32,
2200 ValType::I32,
2201 ValType::I32,
2202 ValType::I32,
2203 ValType::I32,
2204 ValType::I32,
2205 ValType::I32,
2206 ValType::I32,
2207 ],
2208 vec![ValType::I32],
2209 ),
2210 wrap_future(sock_recv_from)
2211 ),
2212 async_fn!(
2213 "sock_send",
2214 (
2215 vec![
2216 ValType::I32,
2217 ValType::I32,
2218 ValType::I32,
2219 ValType::I32,
2220 ValType::I32,
2221 ],
2222 vec![ValType::I32],
2223 ),
2224 wrap_future(sock_send)
2225 ),
2226 async_fn!(
2227 "sock_send_to",
2228 (
2229 vec![
2230 ValType::I32,
2231 ValType::I32,
2232 ValType::I32,
2233 ValType::I32,
2234 ValType::I32,
2235 ValType::I32,
2236 ValType::I32,
2237 ],
2238 vec![ValType::I32],
2239 ),
2240 wrap_future(sock_send_to)
2241 ),
2242 sync_fn!(
2243 "sock_shutdown",
2244 (vec![ValType::I32, ValType::I32], vec![ValType::I32]),
2245 sock_shutdown
2246 ),
2247 sync_fn!(
2248 "sock_getpeeraddr",
2249 (
2250 vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
2251 vec![ValType::I32],
2252 ),
2253 sock_getpeeraddr
2254 ),
2255 sync_fn!(
2256 "sock_getlocaladdr",
2257 (
2258 vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
2259 vec![ValType::I32],
2260 ),
2261 sock_getlocaladdr
2262 ),
2263 sync_fn!(
2264 "sock_getsockopt",
2265 (
2266 vec![
2267 ValType::I32,
2268 ValType::I32,
2269 ValType::I32,
2270 ValType::I32,
2271 ValType::I32,
2272 ],
2273 vec![ValType::I32],
2274 ),
2275 sock_getsockopt
2276 ),
2277 sync_fn!(
2278 "sock_setsockopt",
2279 (
2280 vec![
2281 ValType::I32,
2282 ValType::I32,
2283 ValType::I32,
2284 ValType::I32,
2285 ValType::I32,
2286 ],
2287 vec![ValType::I32],
2288 ),
2289 sock_setsockopt
2290 ),
2291 async_fn!(
2292 "poll_oneoff",
2293 (
2294 vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
2295 vec![ValType::I32],
2296 ),
2297 wrap_future(poll_oneoff)
2298 ),
2299 async_fn!(
2300 "epoll_oneoff",
2301 (
2302 vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
2303 vec![ValType::I32],
2304 ),
2305 wrap_future(poll_oneoff)
2306 ),
2307 async_fn!(
2308 "sock_lookup_ip",
2309 (
2310 vec![
2311 ValType::I32,
2312 ValType::I32,
2313 ValType::I32,
2314 ValType::I32,
2315 ValType::I32,
2316 ValType::I32,
2317 ],
2318 vec![ValType::I32],
2319 ),
2320 wrap_future(sock_lookup_ip)
2321 ),
2322 sync_fn!(
2323 "sock_getaddrinfo",
2324 (
2325 vec![
2326 ValType::I32,
2327 ValType::I32,
2328 ValType::I32,
2329 ValType::I32,
2330 ValType::I32,
2331 ValType::I32,
2332 ValType::I32,
2333 ValType::I32,
2334 ],
2335 vec![ValType::I32],
2336 ),
2337 sock_getaddrinfo
2338 ),
2339 ]
2340}
2341
2342fn to_wasm_return(r: Result<(), Errno>) -> Vec<WasmValue> {
2343 let code = if let Err(e) = r { e.0 } else { 0 };
2344 log::trace!("wasi return {code}");
2345 vec![WasmValue::from_i32(code as i32)]
2346}
2347
2348impl async_wasi::snapshots::common::memory::Memory for Memory {
2349 fn get_data<T: Sized>(&self, offset: WasmPtr<T>) -> Result<&T, Errno> {
2350 unsafe {
2351 let r = std::mem::size_of::<T>();
2352 let ptr = self
2353 .data_pointer(offset.0 as u32, r as u32)
2354 .map_err(|_| Errno::__WASI_ERRNO_FAULT)?;
2355 Ok(ptr.cast::<T>().as_ref().unwrap())
2356 }
2357 }
2358
2359 fn get_slice<T: Sized>(&self, offset: WasmPtr<T>, len: usize) -> Result<&[T], Errno> {
2360 unsafe {
2361 let r = std::mem::size_of::<T>() * len;
2362 let ptr = self
2363 .data_pointer(offset.0 as u32, r as u32)
2364 .map_err(|_| Errno::__WASI_ERRNO_FAULT)? as *const T;
2365 Ok(std::slice::from_raw_parts(ptr, len))
2366 }
2367 }
2368
2369 fn get_iovec<'a>(
2370 &self,
2371 iovec_ptr: WasmPtr<__wasi_ciovec_t>,
2372 iovec_len: __wasi_size_t,
2373 ) -> Result<Vec<std::io::IoSlice<'a>>, Errno> {
2374 unsafe {
2375 let iovec = self.get_slice(iovec_ptr, iovec_len as usize)?.to_vec();
2376 let mut result = Vec::with_capacity(iovec.len());
2377 for i in iovec {
2378 let ptr = self
2379 .data_pointer(i.buf, i.buf_len)
2380 .map_err(|_| Errno::__WASI_ERRNO_FAULT)?;
2381 let s = std::io::IoSlice::new(std::slice::from_raw_parts(ptr, i.buf_len as usize));
2382 result.push(s);
2383 }
2384 Ok(result)
2385 }
2386 }
2387
2388 fn mut_data<T: Sized>(&mut self, offset: WasmPtr<T>) -> Result<&mut T, Errno> {
2389 unsafe {
2390 let r = std::mem::size_of::<T>();
2391 let ptr = self
2392 .data_pointer_mut(offset.0 as u32, r as u32)
2393 .map_err(|_| Errno::__WASI_ERRNO_FAULT)?;
2394 Ok(ptr.cast::<T>().as_mut().unwrap())
2395 }
2396 }
2397
2398 fn mut_slice<T: Sized>(&mut self, offset: WasmPtr<T>, len: usize) -> Result<&mut [T], Errno> {
2399 unsafe {
2400 let r = std::mem::size_of::<T>() * len;
2401 let ptr = self
2402 .data_pointer_mut(offset.0 as u32, r as u32)
2403 .map_err(|_| Errno::__WASI_ERRNO_FAULT)? as *mut T;
2404 Ok(std::slice::from_raw_parts_mut(ptr, len))
2405 }
2406 }
2407
2408 fn mut_iovec(
2409 &mut self,
2410 iovec_ptr: WasmPtr<async_wasi::snapshots::env::wasi_types::__wasi_iovec_t>,
2411 iovec_len: async_wasi::snapshots::env::wasi_types::__wasi_size_t,
2412 ) -> Result<Vec<std::io::IoSliceMut<'_>>, Errno> {
2413 unsafe {
2414 let iovec = self.get_slice(iovec_ptr, iovec_len as usize)?.to_vec();
2415 let mut result = Vec::with_capacity(iovec.len());
2416 for i in iovec {
2417 let ptr = self
2418 .data_pointer_mut(i.buf, i.buf_len)
2419 .map_err(|_| Errno::__WASI_ERRNO_FAULT)?;
2420 let s = std::io::IoSliceMut::new(std::slice::from_raw_parts_mut(
2421 ptr,
2422 i.buf_len as usize,
2423 ));
2424 result.push(s);
2425 }
2426 Ok(result)
2427 }
2428 }
2429
2430 fn write_data<T: Sized>(&mut self, offset: WasmPtr<T>, data: T) -> Result<(), Errno> {
2431 let p = self.mut_data(offset)?;
2432 *p = data;
2433 Ok(())
2434 }
2435}
2436
2437#[cfg(test)]
2438mod tests {
2439 use super::*;
2440 use crate::{r#async::fiber::AsyncState, Executor, Loader, Store, Validator};
2441
2442 #[tokio::test]
2443 async fn test_async_wasi_module() -> Result<(), Box<dyn std::error::Error>> {
2444 let result = Executor::create(None, None);
2446 assert!(result.is_ok());
2447 let mut executor = result.unwrap();
2448 assert!(!executor.inner.0.is_null());
2449
2450 let result = Store::create();
2452 assert!(result.is_ok());
2453 let mut store = result.unwrap();
2454
2455 let result = AsyncWasiModule::create(Some(vec!["abc"]), Some(vec![("ENV", "1")]));
2457 assert!(result.is_ok());
2458 let mut async_wasi_module = result.unwrap();
2459
2460 let result = executor.register_import_module(&mut store, async_wasi_module.as_mut());
2462 assert!(result.is_ok());
2463
2464 let wasm_file = std::env::current_dir()
2465 .unwrap()
2466 .ancestors()
2467 .nth(2)
2468 .unwrap()
2469 .join("examples/wasmedge-sys/async_hello.wasm");
2470 let module = Loader::create(None)?.from_file(&wasm_file)?;
2471 Validator::create(None)?.validate(&module)?;
2472 let mut instance = executor.register_active_module(&mut store, &module)?;
2473 let mut fn_start = instance.get_func_mut("_start")?;
2474
2475 async fn tick() {
2476 let mut i = 0;
2477 loop {
2478 println!("[tick] i={i}");
2479 tokio::time::sleep(std::time::Duration::from_millis(500)).await;
2480 i += 1;
2481 }
2482 }
2483 tokio::spawn(tick());
2484
2485 let async_state = AsyncState::new();
2486 let _ = executor
2487 .call_func_async(&async_state, &mut fn_start, [])
2488 .await?;
2489
2490 Ok(())
2491 }
2492}