Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/wiggle/tests/pointers.rs
1692 views
1
use proptest::prelude::*;
2
use wiggle::{GuestMemory, GuestPtr};
3
use wiggle_test::{HostMemory, MemArea, WasiCtx, impl_errno};
4
5
wiggle::from_witx!({
6
witx: ["tests/pointers.witx"],
7
});
8
9
impl_errno!(types::Errno);
10
11
impl<'a> pointers::Pointers for WasiCtx<'a> {
12
fn pointers_and_enums(
13
&mut self,
14
memory: &mut GuestMemory<'_>,
15
input1: types::Excuse,
16
input2_ptr: GuestPtr<types::Excuse>,
17
input3_ptr: GuestPtr<types::Excuse>,
18
input4_ptr_ptr: GuestPtr<GuestPtr<types::Excuse>>,
19
) -> Result<(), types::Errno> {
20
println!("BAZ input1 {input1:?}");
21
let input2: types::Excuse = memory.read(input2_ptr).map_err(|e| {
22
eprintln!("input2_ptr error: {e}");
23
types::Errno::InvalidArg
24
})?;
25
println!("input2 {input2:?}");
26
27
// Read enum value from immutable ptr:
28
let input3 = memory.read(input3_ptr).map_err(|e| {
29
eprintln!("input3_ptr error: {e}");
30
types::Errno::InvalidArg
31
})?;
32
println!("input3 {input3:?}");
33
34
// Write enum to mutable ptr:
35
memory.write(input2_ptr, input3).map_err(|e| {
36
eprintln!("input2_ptr error: {e}");
37
types::Errno::InvalidArg
38
})?;
39
println!("wrote to input2_ref {input3:?}");
40
41
// Read ptr value from mutable ptr:
42
let input4_ptr: GuestPtr<types::Excuse> = memory.read(input4_ptr_ptr).map_err(|e| {
43
eprintln!("input4_ptr_ptr error: {e}");
44
types::Errno::InvalidArg
45
})?;
46
47
// Read enum value from that ptr:
48
let input4: types::Excuse = memory.read(input4_ptr).map_err(|e| {
49
eprintln!("input4_ptr error: {e}");
50
types::Errno::InvalidArg
51
})?;
52
println!("input4 {input4:?}");
53
54
// Write ptr value to mutable ptr:
55
memory.write(input4_ptr_ptr, input2_ptr).map_err(|e| {
56
eprintln!("input4_ptr_ptr error: {e}");
57
types::Errno::InvalidArg
58
})?;
59
60
Ok(())
61
}
62
}
63
64
fn excuse_strat() -> impl Strategy<Value = types::Excuse> {
65
prop_oneof![
66
Just(types::Excuse::DogAte),
67
Just(types::Excuse::Traffic),
68
Just(types::Excuse::Sleeping),
69
]
70
.boxed()
71
}
72
73
#[derive(Debug)]
74
struct PointersAndEnumsExercise {
75
pub input1: types::Excuse,
76
pub input2: types::Excuse,
77
pub input2_loc: MemArea,
78
pub input3: types::Excuse,
79
pub input3_loc: MemArea,
80
pub input4: types::Excuse,
81
pub input4_loc: MemArea,
82
pub input4_ptr_loc: MemArea,
83
}
84
85
impl PointersAndEnumsExercise {
86
pub fn strat() -> BoxedStrategy<Self> {
87
(
88
excuse_strat(),
89
excuse_strat(),
90
HostMemory::mem_area_strat(4),
91
excuse_strat(),
92
HostMemory::mem_area_strat(4),
93
excuse_strat(),
94
HostMemory::mem_area_strat(4),
95
HostMemory::mem_area_strat(4),
96
)
97
.prop_map(
98
|(
99
input1,
100
input2,
101
input2_loc,
102
input3,
103
input3_loc,
104
input4,
105
input4_loc,
106
input4_ptr_loc,
107
)| PointersAndEnumsExercise {
108
input1,
109
input2,
110
input2_loc,
111
input3,
112
input3_loc,
113
input4,
114
input4_loc,
115
input4_ptr_loc,
116
},
117
)
118
.prop_filter("non-overlapping pointers", |e| {
119
MemArea::non_overlapping_set(&[
120
e.input2_loc,
121
e.input3_loc,
122
e.input4_loc,
123
e.input4_ptr_loc,
124
])
125
})
126
.boxed()
127
}
128
pub fn test(&self) {
129
let mut ctx = WasiCtx::new();
130
let mut host_memory = HostMemory::new();
131
let mut memory = host_memory.guest_memory();
132
133
memory
134
.write(GuestPtr::new(self.input2_loc.ptr), self.input2)
135
.expect("input2 ref_mut");
136
137
memory
138
.write(GuestPtr::new(self.input3_loc.ptr), self.input3)
139
.expect("input3 ref_mut");
140
141
memory
142
.write(GuestPtr::new(self.input4_loc.ptr), self.input4)
143
.expect("input4 ref_mut");
144
145
memory
146
.write(GuestPtr::new(self.input4_ptr_loc.ptr), self.input4_loc.ptr)
147
.expect("input4 ptr ref_mut");
148
149
let e = pointers::pointers_and_enums(
150
&mut ctx,
151
&mut memory,
152
self.input1 as i32,
153
self.input2_loc.ptr as i32,
154
self.input3_loc.ptr as i32,
155
self.input4_ptr_loc.ptr as i32,
156
)
157
.unwrap();
158
assert_eq!(e, types::Errno::Ok as i32, "errno");
159
160
// Implementation of pointers_and_enums writes input3 to the input2_loc:
161
let written_to_input2_loc: i32 = memory
162
.read(GuestPtr::new(self.input2_loc.ptr))
163
.expect("input2 ref");
164
165
assert_eq!(
166
written_to_input2_loc, self.input3 as i32,
167
"pointers_and_enums written to input2"
168
);
169
170
// Implementation of pointers_and_enums writes input2_loc to input4_ptr_loc:
171
let written_to_input4_ptr: u32 = memory
172
.read(GuestPtr::new(self.input4_ptr_loc.ptr))
173
.expect("input4_ptr_loc ref");
174
175
assert_eq!(
176
written_to_input4_ptr, self.input2_loc.ptr,
177
"pointers_and_enums written to input4_ptr"
178
);
179
}
180
}
181
proptest! {
182
#[test]
183
fn pointers_and_enums(e in PointersAndEnumsExercise::strat()) {
184
e.test();
185
}
186
}
187
188