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