Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wiggle/tests/atoms_async.rs
1692 views
1
use proptest::prelude::*;
2
use std::future::Future;
3
use std::pin::Pin;
4
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
5
use wiggle::{GuestMemory, GuestPtr};
6
use wiggle_test::{HostMemory, MemArea, WasiCtx, impl_errno};
7
8
wiggle::from_witx!({
9
witx: ["tests/atoms.witx"],
10
async: *,
11
});
12
13
impl_errno!(types::Errno);
14
15
#[wiggle::async_trait]
16
impl<'a> atoms::Atoms for WasiCtx<'a> {
17
async fn int_float_args(
18
&mut self,
19
_memory: &mut GuestMemory<'_>,
20
an_int: u32,
21
an_float: f32,
22
) -> Result<(), types::Errno> {
23
println!("INT FLOAT ARGS: {an_int} {an_float}");
24
Ok(())
25
}
26
async fn double_int_return_float(
27
&mut self,
28
_memory: &mut GuestMemory<'_>,
29
an_int: u32,
30
) -> Result<types::AliasToFloat, types::Errno> {
31
Ok((an_int as f32) * 2.0)
32
}
33
}
34
35
// There's nothing meaningful to test here - this just demonstrates the test machinery
36
37
#[derive(Debug)]
38
struct IntFloatExercise {
39
pub an_int: u32,
40
pub an_float: f32,
41
}
42
43
impl IntFloatExercise {
44
pub fn test(&self) {
45
let mut ctx = WasiCtx::new();
46
let mut host_memory = HostMemory::new();
47
let mut memory = host_memory.guest_memory();
48
49
let e = run(atoms::int_float_args(
50
&mut ctx,
51
&mut memory,
52
self.an_int as i32,
53
self.an_float,
54
))
55
.unwrap();
56
57
assert_eq!(e, types::Errno::Ok as i32, "int_float_args error");
58
}
59
60
pub fn strat() -> BoxedStrategy<Self> {
61
(prop::num::u32::ANY, prop::num::f32::ANY)
62
.prop_map(|(an_int, an_float)| IntFloatExercise { an_int, an_float })
63
.boxed()
64
}
65
}
66
67
proptest! {
68
#[test]
69
fn int_float_exercise(e in IntFloatExercise::strat()) {
70
e.test()
71
}
72
}
73
#[derive(Debug)]
74
struct DoubleIntExercise {
75
pub input: u32,
76
pub return_loc: MemArea,
77
}
78
79
impl DoubleIntExercise {
80
pub fn test(&self) {
81
let mut ctx = WasiCtx::new();
82
let mut host_memory = HostMemory::new();
83
let mut memory = host_memory.guest_memory();
84
85
let e = run(atoms::double_int_return_float(
86
&mut ctx,
87
&mut memory,
88
self.input as i32,
89
self.return_loc.ptr as i32,
90
))
91
.unwrap();
92
93
let return_val = memory
94
.read(GuestPtr::<types::AliasToFloat>::new(self.return_loc.ptr))
95
.expect("failed to read return");
96
assert_eq!(e, types::Errno::Ok as i32, "errno");
97
assert_eq!(return_val, (self.input as f32) * 2.0, "return val");
98
}
99
100
pub fn strat() -> BoxedStrategy<Self> {
101
(prop::num::u32::ANY, HostMemory::mem_area_strat(4))
102
.prop_map(|(input, return_loc)| DoubleIntExercise { input, return_loc })
103
.boxed()
104
}
105
}
106
107
proptest! {
108
#[test]
109
fn double_int_return_float(e in DoubleIntExercise::strat()) {
110
e.test()
111
}
112
}
113
114
fn run<F: Future>(future: F) -> F::Output {
115
let mut f = Pin::from(Box::new(future));
116
let waker = dummy_waker();
117
let mut cx = Context::from_waker(&waker);
118
loop {
119
match f.as_mut().poll(&mut cx) {
120
Poll::Ready(val) => break val,
121
Poll::Pending => {}
122
}
123
}
124
}
125
126
fn dummy_waker() -> Waker {
127
return unsafe { Waker::from_raw(clone(5 as *const _)) };
128
129
unsafe fn clone(ptr: *const ()) -> RawWaker {
130
assert_eq!(ptr as usize, 5);
131
const VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake_by_ref, drop);
132
RawWaker::new(ptr, &VTABLE)
133
}
134
135
unsafe fn wake(ptr: *const ()) {
136
assert_eq!(ptr as usize, 5);
137
}
138
139
unsafe fn wake_by_ref(ptr: *const ()) {
140
assert_eq!(ptr as usize, 5);
141
}
142
143
unsafe fn drop(ptr: *const ()) {
144
assert_eq!(ptr as usize, 5);
145
}
146
}
147
148