wasmer_wasix/utils/
mod.rs1mod dummy_waker;
2mod owned_mutex_guard;
3pub mod store;
4pub mod thread_local_executor;
5mod thread_parker;
6
7#[cfg(feature = "js")]
8pub(crate) mod web;
9
10pub use self::{dummy_waker::WasiDummyWaker, thread_parker::WasiParkingLot};
11
12pub(crate) use owned_mutex_guard::{
13 OwnedRwLockReadGuard, OwnedRwLockWriteGuard, read_owned, write_owned,
14};
15
16use std::collections::BTreeSet;
17
18use wasmer::Module;
19use wasmer_wasix_types::wasi::Errno;
20
21pub fn is_wasi_module(module: &Module) -> bool {
24 get_wasi_version(module, false).is_some()
25}
26
27pub fn is_wasix_module(module: &Module) -> bool {
29 match get_wasi_versions(module, false).ok_or(false) {
30 Ok(wasi_versions) => {
31 wasi_versions.contains(&WasiVersion::Wasix32v1)
32 || wasi_versions.contains(&WasiVersion::Wasix64v1)
33 }
34 Err(_) => false,
35 }
36}
37
38pub fn map_io_err(err: std::io::Error) -> Errno {
39 From::<std::io::Error>::from(err)
40}
41
42#[cfg(feature = "journal")]
43pub fn map_snapshot_err(err: anyhow::Error) -> Errno {
44 tracing::warn!("unknown snapshot error: {}", err);
45 Errno::Unknown
46}
47
48#[derive(Debug, Clone, Copy, Eq)]
51pub enum WasiVersion {
52 Snapshot0,
54
55 Snapshot1,
57
58 Wasix32v1,
60
61 Wasix64v1,
63
64 Latest,
75}
76
77impl WasiVersion {
78 pub const fn get_namespace_str(&self) -> &'static str {
80 match *self {
81 WasiVersion::Snapshot0 => SNAPSHOT0_NAMESPACE,
82 WasiVersion::Snapshot1 => SNAPSHOT1_NAMESPACE,
83 WasiVersion::Wasix32v1 => WASIX_32V1_NAMESPACE,
84 WasiVersion::Wasix64v1 => WASIX_64V1_NAMESPACE,
85 WasiVersion::Latest => SNAPSHOT1_NAMESPACE,
86 }
87 }
88}
89
90impl PartialEq<WasiVersion> for WasiVersion {
91 fn eq(&self, other: &Self) -> bool {
92 matches!(
93 (*self, *other),
94 (Self::Snapshot1, Self::Latest)
95 | (Self::Latest, Self::Snapshot1)
96 | (Self::Latest, Self::Latest)
97 | (Self::Snapshot0, Self::Snapshot0)
98 | (Self::Snapshot1, Self::Snapshot1)
99 | (Self::Wasix32v1, Self::Wasix32v1)
100 | (Self::Wasix64v1, Self::Wasix64v1)
101 )
102 }
103}
104
105impl PartialOrd for WasiVersion {
106 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
107 Some(self.cmp(other))
108 }
109}
110
111impl Ord for WasiVersion {
112 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
113 if self == other {
114 return std::cmp::Ordering::Equal;
115 }
116 match (*self, *other) {
117 (Self::Snapshot1, Self::Snapshot0) => std::cmp::Ordering::Greater,
118 (Self::Wasix32v1, Self::Snapshot1) | (Self::Wasix32v1, Self::Snapshot0) => {
119 std::cmp::Ordering::Greater
120 }
121 (Self::Wasix64v1, Self::Wasix32v1)
122 | (Self::Wasix64v1, Self::Snapshot1)
123 | (Self::Wasix64v1, Self::Snapshot0) => std::cmp::Ordering::Greater,
124 (Self::Latest, Self::Wasix64v1)
125 | (Self::Latest, Self::Wasix32v1)
126 | (Self::Latest, Self::Snapshot1)
127 | (Self::Latest, Self::Snapshot0) => std::cmp::Ordering::Greater,
128 (_, _) => std::cmp::Ordering::Less,
130 }
131 }
132}
133
134const SNAPSHOT0_NAMESPACE: &str = "wasi_unstable";
136
137const SNAPSHOT1_NAMESPACE: &str = "wasi_snapshot_preview1";
139
140const WASIX_32V1_NAMESPACE: &str = "wasix_32v1";
142
143const WASIX_64V1_NAMESPACE: &str = "wasix_64v1";
145
146const WASIX_HTTP_V1_NAMESPACE: &str = "wasix_http_client_v1";
148
149pub fn get_wasi_version(module: &Module, strict: bool) -> Option<WasiVersion> {
157 let mut imports = module.imports().functions().map(|f| f.module().to_owned());
158
159 if strict {
160 let first_module = imports.next()?;
161 if imports.all(|module| module == first_module) {
162 match first_module.as_str() {
163 SNAPSHOT0_NAMESPACE => Some(WasiVersion::Snapshot0),
164 SNAPSHOT1_NAMESPACE => Some(WasiVersion::Snapshot1),
165 WASIX_32V1_NAMESPACE => Some(WasiVersion::Wasix32v1),
166 WASIX_64V1_NAMESPACE => Some(WasiVersion::Wasix64v1),
167 _ => None,
168 }
169 } else {
170 None
171 }
172 } else {
173 imports.find_map(|module| match module.as_str() {
176 SNAPSHOT0_NAMESPACE => Some(WasiVersion::Snapshot0),
177 SNAPSHOT1_NAMESPACE => Some(WasiVersion::Snapshot1),
178 WASIX_32V1_NAMESPACE => Some(WasiVersion::Wasix32v1),
179 WASIX_64V1_NAMESPACE => Some(WasiVersion::Wasix64v1),
180 _ => None,
181 })
182 }
183}
184
185pub fn get_wasi_versions(module: &Module, strict: bool) -> Option<BTreeSet<WasiVersion>> {
190 let mut out = BTreeSet::new();
191 let imports = module.imports().functions().map(|f| f.module().to_owned());
192
193 let mut non_wasi_seen = false;
194 for ns in imports {
195 match ns.as_str() {
196 SNAPSHOT0_NAMESPACE => {
197 out.insert(WasiVersion::Snapshot0);
198 }
199 SNAPSHOT1_NAMESPACE => {
200 out.insert(WasiVersion::Snapshot1);
201 }
202 WASIX_32V1_NAMESPACE => {
203 out.insert(WasiVersion::Wasix32v1);
204 }
205 WASIX_64V1_NAMESPACE => {
206 out.insert(WasiVersion::Wasix64v1);
207 }
208 WASIX_HTTP_V1_NAMESPACE => {
209 out.insert(WasiVersion::Wasix64v1);
210 }
211 _ => {
212 non_wasi_seen = true;
213 }
214 }
215 }
216 if strict && non_wasi_seen {
217 None
218 } else {
219 Some(out)
220 }
221}
222
223#[cfg(test)]
224mod test {
225 use super::*;
226
227 #[test]
228 fn wasi_version_equality() {
229 assert_eq!(WasiVersion::Snapshot0, WasiVersion::Snapshot0);
230 assert_eq!(WasiVersion::Wasix64v1, WasiVersion::Wasix64v1);
231 assert_eq!(WasiVersion::Wasix32v1, WasiVersion::Wasix32v1);
232 assert_eq!(WasiVersion::Snapshot1, WasiVersion::Snapshot1);
233 assert_eq!(WasiVersion::Snapshot1, WasiVersion::Latest);
234 assert_eq!(WasiVersion::Latest, WasiVersion::Snapshot1);
235 assert_eq!(WasiVersion::Latest, WasiVersion::Latest);
236 assert!(WasiVersion::Wasix32v1 != WasiVersion::Wasix64v1);
237 assert!(WasiVersion::Wasix64v1 != WasiVersion::Wasix32v1);
238 assert!(WasiVersion::Snapshot1 != WasiVersion::Wasix64v1);
239 assert!(WasiVersion::Wasix64v1 != WasiVersion::Snapshot1);
240 assert!(WasiVersion::Snapshot1 != WasiVersion::Wasix32v1);
241 assert!(WasiVersion::Wasix32v1 != WasiVersion::Snapshot1);
242 assert!(WasiVersion::Snapshot0 != WasiVersion::Snapshot1);
243 assert!(WasiVersion::Snapshot1 != WasiVersion::Snapshot0);
244 assert!(WasiVersion::Snapshot0 != WasiVersion::Latest);
245 assert!(WasiVersion::Latest != WasiVersion::Snapshot0);
246 assert!(WasiVersion::Snapshot0 != WasiVersion::Latest);
247 assert!(WasiVersion::Latest != WasiVersion::Snapshot0);
248 assert!(WasiVersion::Wasix32v1 != WasiVersion::Latest);
249 assert!(WasiVersion::Wasix64v1 != WasiVersion::Latest);
250 }
251
252 #[test]
253 fn wasi_version_ordering() {
254 assert!(WasiVersion::Snapshot0 <= WasiVersion::Snapshot0);
255 assert!(WasiVersion::Snapshot1 <= WasiVersion::Snapshot1);
256 assert!(WasiVersion::Wasix32v1 <= WasiVersion::Wasix32v1);
257 assert!(WasiVersion::Wasix64v1 <= WasiVersion::Wasix64v1);
258 assert!(WasiVersion::Latest <= WasiVersion::Latest);
259 assert!(WasiVersion::Snapshot0 >= WasiVersion::Snapshot0);
260 assert!(WasiVersion::Snapshot1 >= WasiVersion::Snapshot1);
261 assert!(WasiVersion::Wasix32v1 >= WasiVersion::Wasix32v1);
262 assert!(WasiVersion::Wasix64v1 >= WasiVersion::Wasix64v1);
263 assert!(WasiVersion::Latest >= WasiVersion::Latest);
264
265 assert!(WasiVersion::Snapshot0 < WasiVersion::Latest);
266 assert!(WasiVersion::Snapshot0 < WasiVersion::Wasix32v1);
267 assert!(WasiVersion::Snapshot0 < WasiVersion::Wasix64v1);
268 assert!(WasiVersion::Snapshot0 < WasiVersion::Snapshot1);
269 assert!(WasiVersion::Latest > WasiVersion::Snapshot0);
270 assert!(WasiVersion::Wasix32v1 > WasiVersion::Snapshot0);
271 assert!(WasiVersion::Wasix64v1 > WasiVersion::Snapshot0);
272 assert!(WasiVersion::Snapshot1 > WasiVersion::Snapshot0);
273
274 assert!(WasiVersion::Snapshot1 < WasiVersion::Wasix32v1);
275 assert!(WasiVersion::Snapshot1 < WasiVersion::Wasix64v1);
276 assert!(WasiVersion::Wasix32v1 > WasiVersion::Snapshot1);
277 assert!(WasiVersion::Wasix64v1 > WasiVersion::Snapshot1);
278
279 assert!(WasiVersion::Wasix32v1 < WasiVersion::Latest);
280 assert!(WasiVersion::Wasix32v1 > WasiVersion::Snapshot1);
281 assert!(WasiVersion::Wasix64v1 < WasiVersion::Latest);
282 assert!(WasiVersion::Wasix64v1 > WasiVersion::Snapshot1);
283 assert!(WasiVersion::Latest > WasiVersion::Wasix32v1);
284 assert!(WasiVersion::Snapshot1 < WasiVersion::Wasix32v1);
285 assert!(WasiVersion::Latest > WasiVersion::Wasix64v1);
286 assert!(WasiVersion::Snapshot1 < WasiVersion::Wasix32v1);
287
288 assert!(WasiVersion::Wasix32v1 < WasiVersion::Wasix64v1);
289 assert!(WasiVersion::Wasix64v1 > WasiVersion::Wasix32v1);
290 }
291}