@wasm-oj/server 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -0
  3. package/THIRD_PARTY_NOTICES.md +302 -0
  4. package/crates/runtime-core/Cargo.lock +5099 -0
  5. package/crates/runtime-core/Cargo.toml +66 -0
  6. package/crates/runtime-core/README.md +47 -0
  7. package/crates/runtime-core/src/bin/wasm-oj-compiler.rs +418 -0
  8. package/crates/runtime-core/src/bin/wasm-oj-runner.rs +294 -0
  9. package/crates/runtime-core/src/capabilities.rs +118 -0
  10. package/crates/runtime-core/src/compiler.rs +658 -0
  11. package/crates/runtime-core/src/contract.rs +5 -0
  12. package/crates/runtime-core/src/deterministic.rs +1051 -0
  13. package/crates/runtime-core/src/error.rs +58 -0
  14. package/crates/runtime-core/src/filesystem.rs +547 -0
  15. package/crates/runtime-core/src/filesystem_quota.rs +167 -0
  16. package/crates/runtime-core/src/go_compiler_session.rs +297 -0
  17. package/crates/runtime-core/src/interactive.rs +1019 -0
  18. package/crates/runtime-core/src/judge_package.rs +1539 -0
  19. package/crates/runtime-core/src/lib.rs +98 -0
  20. package/crates/runtime-core/src/memory.rs +84 -0
  21. package/crates/runtime-core/src/meter.rs +549 -0
  22. package/crates/runtime-core/src/module_imports.rs +149 -0
  23. package/crates/runtime-core/src/module_policy.rs +714 -0
  24. package/crates/runtime-core/src/output.rs +204 -0
  25. package/crates/runtime-core/src/run/mod.rs +208 -0
  26. package/crates/runtime-core/src/run/native.rs +260 -0
  27. package/crates/runtime-core/src/run/web.rs +229 -0
  28. package/crates/runtime-core/src/run/web_runtime.rs +109 -0
  29. package/crates/runtime-core/src/types.rs +268 -0
  30. package/crates/runtime-core/src/web.rs +83 -0
  31. package/dist/chunks/go-toolchain-Dbt-lp2L.js +426 -0
  32. package/dist/chunks/java-toolchain-DajoRCHu.js +44 -0
  33. package/dist/chunks/python-toolchain-Dx834o2A.js +4 -0
  34. package/dist/chunks/rust-toolchain-CJ3sMxPE.js +252 -0
  35. package/dist/chunks/toolchains-C6KuA1yM.js +224 -0
  36. package/dist/go-stage.mjs +193 -0
  37. package/dist/index.d.ts +221 -0
  38. package/dist/index.js +4393 -0
  39. package/dist/java-stage.mjs +111 -0
  40. package/dist/python-stage.mjs +90 -0
  41. package/dist/rustc-stage.mjs +301 -0
  42. package/dist/server-build-stage.mjs +2564 -0
  43. package/dist/server-runner-stage.mjs +155 -0
  44. package/licenses/fflate-MIT.txt +21 -0
  45. package/licenses/runtime-core-dependencies.html +6253 -0
  46. package/licenses/runtime-core-dependencies.json +3041 -0
  47. package/licenses/wasmer-sdk-MIT.txt +21 -0
  48. package/licenses/wasmer-sdk-dependencies.html +6901 -0
  49. package/licenses/wasmer-sdk-dependencies.json +3013 -0
  50. package/package.json +70 -0
  51. package/rust-toolchain.toml +5 -0
  52. package/testdata/wojjdg02-v2-text.hex +1 -0
  53. package/vendor/shared-buffer/Cargo.toml +22 -0
  54. package/vendor/shared-buffer/LICENSE_APACHE.md +176 -0
  55. package/vendor/shared-buffer/LICENSE_MIT.md +25 -0
  56. package/vendor/shared-buffer/README.md +34 -0
  57. package/vendor/shared-buffer/src/lib.rs +58 -0
  58. package/vendor/shared-buffer/src/mmap.rs +250 -0
  59. package/vendor/shared-buffer/src/owned.rs +389 -0
  60. package/vendor/virtual-fs/Cargo.toml +181 -0
  61. package/vendor/virtual-fs/LICENSE +25 -0
  62. package/vendor/virtual-fs/src/arc_box_file.rs +142 -0
  63. package/vendor/virtual-fs/src/arc_file.rs +182 -0
  64. package/vendor/virtual-fs/src/arc_fs.rs +68 -0
  65. package/vendor/virtual-fs/src/buffer_file.rs +103 -0
  66. package/vendor/virtual-fs/src/builder.rs +232 -0
  67. package/vendor/virtual-fs/src/combine_file.rs +101 -0
  68. package/vendor/virtual-fs/src/cow_file.rs +345 -0
  69. package/vendor/virtual-fs/src/dual_write_file.rs +113 -0
  70. package/vendor/virtual-fs/src/empty_fs.rs +81 -0
  71. package/vendor/virtual-fs/src/filesystems.rs +108 -0
  72. package/vendor/virtual-fs/src/host_fs.rs +1390 -0
  73. package/vendor/virtual-fs/src/lib.rs +782 -0
  74. package/vendor/virtual-fs/src/limiter.rs +252 -0
  75. package/vendor/virtual-fs/src/mem_fs/file.rs +1799 -0
  76. package/vendor/virtual-fs/src/mem_fs/file_opener.rs +941 -0
  77. package/vendor/virtual-fs/src/mem_fs/filesystem.rs +2134 -0
  78. package/vendor/virtual-fs/src/mem_fs/mod.rs +245 -0
  79. package/vendor/virtual-fs/src/mem_fs/offloaded_file.rs +474 -0
  80. package/vendor/virtual-fs/src/mem_fs/stdio.rs +318 -0
  81. package/vendor/virtual-fs/src/mount_fs.rs +2225 -0
  82. package/vendor/virtual-fs/src/null_file.rs +87 -0
  83. package/vendor/virtual-fs/src/ops.rs +364 -0
  84. package/vendor/virtual-fs/src/overlay_fs.rs +2216 -0
  85. package/vendor/virtual-fs/src/passthru_fs.rs +119 -0
  86. package/vendor/virtual-fs/src/pipe.rs +603 -0
  87. package/vendor/virtual-fs/src/random_file.rs +88 -0
  88. package/vendor/virtual-fs/src/special_file.rs +108 -0
  89. package/vendor/virtual-fs/src/static_file.rs +133 -0
  90. package/vendor/virtual-fs/src/static_fs.rs +460 -0
  91. package/vendor/virtual-fs/src/tmp_fs.rs +95 -0
  92. package/vendor/virtual-fs/src/trace_fs.rs +258 -0
  93. package/vendor/virtual-fs/src/webc_volume_fs.rs +829 -0
  94. package/vendor/virtual-fs/src/zero_file.rs +90 -0
@@ -0,0 +1,119 @@
1
+ //! Wraps a boxed file system with an implemented trait VirtualSystem - this is
2
+ //! needed so that a `Box<dyn VirtualFileSystem>` can be wrapped in an Arc and
3
+ //! shared - some of the interfaces pass around a `Box<dyn VirtualFileSystem>`
4
+
5
+ use std::{path::Path, sync::Arc};
6
+
7
+ use crate::*;
8
+
9
+ #[derive(Debug)]
10
+ pub struct PassthruFileSystem {
11
+ fs: Arc<dyn FileSystem + Send + Sync + 'static>,
12
+ }
13
+
14
+ impl PassthruFileSystem {
15
+ /// Creates a new PassthruFileSystem that wraps the given FileSystem.
16
+ // NOTE: only kept for backwards compatibility.
17
+ // TODO: change to only accept Arc, and remove Self::new_arc in the next breaking API change!
18
+ pub fn new(inner: Box<dyn FileSystem + Send + Sync + 'static>) -> Self {
19
+ Self { fs: inner.into() }
20
+ }
21
+
22
+ pub fn new_arc(inner: Arc<dyn FileSystem + Send + Sync + 'static>) -> Self {
23
+ Self { fs: inner }
24
+ }
25
+ }
26
+
27
+ impl FileSystem for PassthruFileSystem {
28
+ fn readlink(&self, path: &Path) -> Result<PathBuf> {
29
+ self.fs.readlink(path)
30
+ }
31
+
32
+ fn read_dir(&self, path: &Path) -> Result<ReadDir> {
33
+ self.fs.read_dir(path)
34
+ }
35
+
36
+ fn create_dir(&self, path: &Path) -> Result<()> {
37
+ self.fs.create_dir(path)
38
+ }
39
+
40
+ fn create_symlink(&self, source: &Path, target: &Path) -> Result<()> {
41
+ self.fs.create_symlink(source, target)
42
+ }
43
+
44
+ fn hard_link(&self, source: &Path, target: &Path) -> Result<()> {
45
+ self.fs.hard_link(source, target)
46
+ }
47
+
48
+ fn remove_dir(&self, path: &Path) -> Result<()> {
49
+ self.fs.remove_dir(path)
50
+ }
51
+
52
+ fn rename<'a>(&'a self, from: &'a Path, to: &'a Path) -> BoxFuture<'a, Result<()>> {
53
+ Box::pin(async { self.fs.rename(from, to).await })
54
+ }
55
+
56
+ fn metadata(&self, path: &Path) -> Result<Metadata> {
57
+ self.fs.metadata(path)
58
+ }
59
+
60
+ fn symlink_metadata(&self, path: &Path) -> Result<Metadata> {
61
+ self.fs.symlink_metadata(path)
62
+ }
63
+
64
+ fn remove_file(&self, path: &Path) -> Result<()> {
65
+ self.fs.remove_file(path)
66
+ }
67
+
68
+ fn new_open_options(&self) -> OpenOptions<'_> {
69
+ self.fs.new_open_options()
70
+ }
71
+ }
72
+
73
+ #[cfg(test)]
74
+ mod test_builder {
75
+ use std::sync::Arc;
76
+
77
+ use tokio::io::{AsyncReadExt, AsyncWriteExt};
78
+
79
+ use crate::{FileSystem, PassthruFileSystem};
80
+
81
+ #[tokio::test]
82
+ async fn test_passthru_fs_2() {
83
+ let mem_fs = crate::mem_fs::FileSystem::default();
84
+
85
+ mem_fs
86
+ .new_open_options()
87
+ .read(true)
88
+ .write(true)
89
+ .create(true)
90
+ .open("/foo.txt")
91
+ .unwrap()
92
+ .write_all(b"hello")
93
+ .await
94
+ .unwrap();
95
+
96
+ let mut buf = Vec::new();
97
+ mem_fs
98
+ .new_open_options()
99
+ .read(true)
100
+ .open("/foo.txt")
101
+ .unwrap()
102
+ .read_to_end(&mut buf)
103
+ .await
104
+ .unwrap();
105
+ assert_eq!(buf, b"hello");
106
+
107
+ let passthru_fs = PassthruFileSystem::new_arc(Arc::new(mem_fs.clone()));
108
+ let mut buf = Vec::new();
109
+ passthru_fs
110
+ .new_open_options()
111
+ .read(true)
112
+ .open("/foo.txt")
113
+ .unwrap()
114
+ .read_to_end(&mut buf)
115
+ .await
116
+ .unwrap();
117
+ assert_eq!(buf, b"hello");
118
+ }
119
+ }
@@ -0,0 +1,603 @@
1
+ use bytes::{Buf, Bytes};
2
+ use std::pin::Pin;
3
+ use std::sync::Arc;
4
+ use std::sync::Mutex;
5
+ use std::task::Context;
6
+ use std::task::Poll;
7
+ use std::{io::IoSlice, sync::MutexGuard};
8
+ use std::{
9
+ io::{self, Read, Seek, SeekFrom},
10
+ sync::Weak,
11
+ };
12
+ use tokio::sync::mpsc;
13
+ use tokio::{
14
+ io::{AsyncRead, AsyncSeek, AsyncWrite},
15
+ sync::mpsc::error::TryRecvError,
16
+ };
17
+ use virtual_mio::{InterestHandler, InterestType};
18
+
19
+ use crate::{ArcFile, FsError, VirtualFile};
20
+
21
+ // Each pipe end is separately cloneable. The overall pipe
22
+ // remains open as long as at least one tx end and one rx
23
+ // end are still alive.
24
+ // As such, closing a pipe isn't a well-defined operation,
25
+ // since more references to the ends may still be alive.
26
+ #[derive(Debug, Clone)]
27
+ pub struct Pipe {
28
+ /// Transmit side of the pipe
29
+ send: PipeTx,
30
+ /// Receive side of the pipe
31
+ recv: PipeRx,
32
+ }
33
+
34
+ #[derive(Debug, Clone)]
35
+ pub struct PipeTx {
36
+ /// Sends bytes down the pipe
37
+ tx: Option<mpsc::UnboundedSender<Vec<u8>>>,
38
+ rx_end: Weak<Mutex<PipeReceiver>>,
39
+ }
40
+
41
+ #[derive(Debug, Clone)]
42
+ pub struct PipeRx {
43
+ /// Receives bytes from the pipe
44
+ /// Also, buffers the last read message from the pipe while its being consumed
45
+ rx: Option<Arc<Mutex<PipeReceiver>>>,
46
+ }
47
+
48
+ impl PipeRx {
49
+ // Tries to read from the internal buffer if data is available.
50
+ fn try_read_from_buffer(
51
+ rx: &mut MutexGuard<'_, PipeReceiver>,
52
+ max_len: usize,
53
+ // Should return how much actual data was read from the provided slice
54
+ write: impl FnOnce(&[u8]) -> Option<usize>,
55
+ ) -> Option<usize> {
56
+ rx.buffer.as_mut().and_then(|read_buffer| {
57
+ let buf_len = read_buffer.len();
58
+ if buf_len > 0 {
59
+ let mut read = buf_len.min(max_len);
60
+ let inner_buf = &read_buffer[..read];
61
+ // read = ?;
62
+ read = write(inner_buf)?;
63
+ read_buffer.advance(read);
64
+ Some(read)
65
+ } else {
66
+ None
67
+ }
68
+ })
69
+ }
70
+
71
+ pub fn close(&mut self) {
72
+ _ = self.rx.take();
73
+ }
74
+
75
+ pub fn try_read(&mut self, buf: &mut [u8]) -> Option<usize> {
76
+ let Some(ref mut rx) = self.rx else {
77
+ return Some(0);
78
+ };
79
+
80
+ let mut rx = rx.lock().unwrap();
81
+ loop {
82
+ if let Some(read) = Self::try_read_from_buffer(&mut rx, buf.len(), |mut read_buf| {
83
+ Read::read(&mut read_buf, buf).ok()
84
+ }) {
85
+ return Some(read);
86
+ };
87
+
88
+ let data = {
89
+ match rx.chan.try_recv() {
90
+ Ok(a) => a,
91
+ Err(TryRecvError::Empty) => {
92
+ return None;
93
+ }
94
+ Err(TryRecvError::Disconnected) => {
95
+ return Some(0);
96
+ }
97
+ }
98
+ };
99
+ rx.buffer.replace(Bytes::from(data));
100
+ }
101
+ }
102
+
103
+ pub fn poll_read_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
104
+ let Some(ref rx) = self.rx else {
105
+ return Poll::Ready(Err(std::io::Error::new(
106
+ std::io::ErrorKind::BrokenPipe,
107
+ "PipeRx is closed",
108
+ )));
109
+ };
110
+
111
+ let mut rx = rx.lock().unwrap();
112
+ loop {
113
+ {
114
+ if let Some(inner_buf) = rx.buffer.as_mut() {
115
+ let buf_len = inner_buf.len();
116
+ if buf_len > 0 {
117
+ return Poll::Ready(Ok(buf_len));
118
+ }
119
+ }
120
+ }
121
+
122
+ let mut pinned_rx = Pin::new(&mut rx.chan);
123
+ let data = match pinned_rx.poll_recv(cx) {
124
+ Poll::Ready(Some(a)) => a,
125
+ Poll::Ready(None) => return Poll::Ready(Ok(0)),
126
+ Poll::Pending => return Poll::Pending,
127
+ };
128
+
129
+ rx.buffer.replace(Bytes::from(data));
130
+ }
131
+ }
132
+
133
+ pub fn set_interest_handler(&self, interest_handler: Box<dyn InterestHandler>) {
134
+ let Some(ref rx) = self.rx else {
135
+ return;
136
+ };
137
+ let mut rx = rx.lock().unwrap();
138
+ rx.interest_handler.replace(interest_handler);
139
+ }
140
+
141
+ pub fn remove_interest_handler(&self) -> Option<Box<dyn InterestHandler>> {
142
+ let rx = self.rx.as_ref()?;
143
+ let mut rx = rx.lock().unwrap();
144
+ rx.interest_handler.take()
145
+ }
146
+ }
147
+
148
+ #[derive(Debug)]
149
+ struct PipeReceiver {
150
+ // Note: Since we need to store the buffer alongside the
151
+ // actual receiver, we can't make use of an mpmc channel
152
+ chan: mpsc::UnboundedReceiver<Vec<u8>>,
153
+ buffer: Option<Bytes>,
154
+ interest_handler: Option<Box<dyn InterestHandler>>,
155
+ }
156
+
157
+ impl Pipe {
158
+ pub fn new() -> Self {
159
+ let (tx, rx) = mpsc::unbounded_channel();
160
+
161
+ let recv = Arc::new(Mutex::new(PipeReceiver {
162
+ chan: rx,
163
+ buffer: None,
164
+ interest_handler: None,
165
+ }));
166
+ Pipe {
167
+ send: PipeTx {
168
+ tx: Some(tx),
169
+ rx_end: Arc::downgrade(&recv),
170
+ },
171
+ recv: PipeRx { rx: Some(recv) },
172
+ }
173
+ }
174
+
175
+ pub fn channel() -> (Pipe, Pipe) {
176
+ let (tx1, rx1) = Pipe::new().split();
177
+ let (tx2, rx2) = Pipe::new().split();
178
+
179
+ let end1 = Pipe::combine(tx1, rx2);
180
+ let end2 = Pipe::combine(tx2, rx1);
181
+ (end1, end2)
182
+ }
183
+
184
+ pub fn split(self) -> (PipeTx, PipeRx) {
185
+ (self.send, self.recv)
186
+ }
187
+
188
+ pub fn combine(tx: PipeTx, rx: PipeRx) -> Self {
189
+ Self { send: tx, recv: rx }
190
+ }
191
+
192
+ pub fn try_read(&mut self, buf: &mut [u8]) -> Option<usize> {
193
+ self.recv.try_read(buf)
194
+ }
195
+
196
+ pub fn close(&mut self) {
197
+ self.send.close();
198
+ self.recv.close();
199
+ }
200
+
201
+ pub fn set_interest_handler(&self, interest_handler: Box<dyn InterestHandler>) {
202
+ self.recv.set_interest_handler(interest_handler);
203
+ }
204
+
205
+ pub fn remove_interest_handler(&self) -> Option<Box<dyn InterestHandler>> {
206
+ self.recv.remove_interest_handler()
207
+ }
208
+ }
209
+
210
+ impl Default for Pipe {
211
+ fn default() -> Self {
212
+ Self::new()
213
+ }
214
+ }
215
+
216
+ impl PipeTx {
217
+ pub fn close(&mut self) {
218
+ _ = self.tx.take();
219
+ }
220
+
221
+ pub fn poll_write_ready(self: Pin<&mut Self>) -> Poll<io::Result<usize>> {
222
+ let Some(ref tx) = self.tx else {
223
+ return Poll::Ready(Err(std::io::Error::new(
224
+ std::io::ErrorKind::BrokenPipe,
225
+ "PipeTx is closed",
226
+ )));
227
+ };
228
+
229
+ if tx.is_closed() {
230
+ Poll::Ready(Ok(0))
231
+ } else {
232
+ Poll::Ready(Ok(8192))
233
+ }
234
+ }
235
+
236
+ fn mark_other_end_readable(&self) {
237
+ if let Some(rx_end) = self.rx_end.upgrade() {
238
+ let mut guard = rx_end.lock().unwrap();
239
+ if let Some(interest_handler) = guard.interest_handler.as_mut() {
240
+ interest_handler.push_interest(InterestType::Readable);
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ impl Seek for Pipe {
247
+ fn seek(&mut self, from: SeekFrom) -> io::Result<u64> {
248
+ self.recv.seek(from)
249
+ }
250
+ }
251
+
252
+ impl Seek for PipeRx {
253
+ fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
254
+ Ok(0)
255
+ }
256
+ }
257
+
258
+ impl Seek for PipeTx {
259
+ fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
260
+ Ok(0)
261
+ }
262
+ }
263
+
264
+ impl Read for Pipe {
265
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
266
+ self.recv.read(buf)
267
+ }
268
+ }
269
+
270
+ impl Read for PipeRx {
271
+ fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
272
+ let Some(ref mut rx) = self.rx else {
273
+ return Err(std::io::Error::new(
274
+ std::io::ErrorKind::BrokenPipe,
275
+ "PipeRx is closed",
276
+ ));
277
+ };
278
+
279
+ let mut rx = rx.lock().unwrap();
280
+ loop {
281
+ if let Some(read) = Self::try_read_from_buffer(&mut rx, buf.len(), |mut read_buf| {
282
+ Read::read(&mut read_buf, buf).ok()
283
+ }) {
284
+ return Ok(read);
285
+ }
286
+
287
+ let data = {
288
+ match rx.chan.blocking_recv() {
289
+ Some(a) => a,
290
+ None => {
291
+ return Ok(0);
292
+ }
293
+ }
294
+ };
295
+ rx.buffer.replace(Bytes::from(data));
296
+ }
297
+ }
298
+ }
299
+
300
+ impl std::io::Write for Pipe {
301
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
302
+ self.send.write(buf)
303
+ }
304
+
305
+ fn flush(&mut self) -> std::io::Result<()> {
306
+ self.send.flush()
307
+ }
308
+
309
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
310
+ self.send.write_all(buf)
311
+ }
312
+
313
+ fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> {
314
+ self.send.write_fmt(fmt)
315
+ }
316
+
317
+ fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
318
+ self.send.write_vectored(bufs)
319
+ }
320
+ }
321
+
322
+ impl std::io::Write for PipeTx {
323
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
324
+ let Some(ref tx) = self.tx else {
325
+ return Err(std::io::Error::new(
326
+ std::io::ErrorKind::BrokenPipe,
327
+ "PipeTx is closed",
328
+ ));
329
+ };
330
+
331
+ tx.send(buf.to_vec())
332
+ .map_err(|_| Into::<std::io::Error>::into(std::io::ErrorKind::BrokenPipe))?;
333
+ self.mark_other_end_readable();
334
+ Ok(buf.len())
335
+ }
336
+
337
+ fn flush(&mut self) -> std::io::Result<()> {
338
+ Ok(())
339
+ }
340
+ }
341
+
342
+ impl AsyncSeek for Pipe {
343
+ fn start_seek(mut self: Pin<&mut Self>, position: SeekFrom) -> io::Result<()> {
344
+ let this = Pin::new(&mut self.recv);
345
+ this.start_seek(position)
346
+ }
347
+
348
+ fn poll_complete(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
349
+ let this = Pin::new(&mut self.recv);
350
+ this.poll_complete(cx)
351
+ }
352
+ }
353
+
354
+ impl AsyncSeek for PipeRx {
355
+ fn start_seek(self: Pin<&mut Self>, _position: SeekFrom) -> io::Result<()> {
356
+ Ok(())
357
+ }
358
+ fn poll_complete(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
359
+ Poll::Ready(Ok(0))
360
+ }
361
+ }
362
+
363
+ impl AsyncSeek for PipeTx {
364
+ fn start_seek(self: Pin<&mut Self>, _position: SeekFrom) -> io::Result<()> {
365
+ Ok(())
366
+ }
367
+ fn poll_complete(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
368
+ Poll::Ready(Ok(0))
369
+ }
370
+ }
371
+
372
+ impl AsyncWrite for Pipe {
373
+ fn poll_write(
374
+ mut self: Pin<&mut Self>,
375
+ cx: &mut Context<'_>,
376
+ buf: &[u8],
377
+ ) -> Poll<io::Result<usize>> {
378
+ let this = Pin::new(&mut self.send);
379
+ this.poll_write(cx, buf)
380
+ }
381
+
382
+ fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
383
+ let this = Pin::new(&mut self.send);
384
+ this.poll_flush(cx)
385
+ }
386
+
387
+ fn poll_shutdown(
388
+ mut self: Pin<&mut Self>,
389
+ cx: &mut Context<'_>,
390
+ ) -> Poll<Result<(), io::Error>> {
391
+ let this = Pin::new(&mut self.send);
392
+ this.poll_shutdown(cx)
393
+ }
394
+
395
+ fn poll_write_vectored(
396
+ mut self: Pin<&mut Self>,
397
+ cx: &mut Context<'_>,
398
+ bufs: &[IoSlice<'_>],
399
+ ) -> Poll<Result<usize, io::Error>> {
400
+ let this = Pin::new(&mut self.send);
401
+ this.poll_write_vectored(cx, bufs)
402
+ }
403
+ }
404
+
405
+ impl AsyncWrite for PipeTx {
406
+ fn poll_write(
407
+ self: Pin<&mut Self>,
408
+ _cx: &mut Context<'_>,
409
+ buf: &[u8],
410
+ ) -> Poll<io::Result<usize>> {
411
+ let Some(ref tx) = self.tx else {
412
+ return Poll::Ready(Err(std::io::Error::new(
413
+ std::io::ErrorKind::BrokenPipe,
414
+ "PipeTx is closed",
415
+ )));
416
+ };
417
+
418
+ match tx.send(buf.to_vec()) {
419
+ Ok(()) => {
420
+ self.mark_other_end_readable();
421
+ Poll::Ready(Ok(buf.len()))
422
+ }
423
+ Err(_) => Poll::Ready(Err(Into::<std::io::Error>::into(
424
+ std::io::ErrorKind::BrokenPipe,
425
+ ))),
426
+ }
427
+ }
428
+
429
+ fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
430
+ Poll::Ready(Ok(()))
431
+ }
432
+
433
+ fn poll_shutdown(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
434
+ self.close();
435
+ Poll::Ready(Ok(()))
436
+ }
437
+ }
438
+
439
+ impl AsyncRead for Pipe {
440
+ fn poll_read(
441
+ mut self: Pin<&mut Self>,
442
+ cx: &mut Context<'_>,
443
+ buf: &mut tokio::io::ReadBuf<'_>,
444
+ ) -> Poll<io::Result<()>> {
445
+ let this = Pin::new(&mut self.recv);
446
+ this.poll_read(cx, buf)
447
+ }
448
+ }
449
+
450
+ impl AsyncRead for PipeRx {
451
+ fn poll_read(
452
+ mut self: Pin<&mut Self>,
453
+ cx: &mut Context<'_>,
454
+ buf: &mut tokio::io::ReadBuf<'_>,
455
+ ) -> Poll<io::Result<()>> {
456
+ let Some(ref mut rx) = self.rx else {
457
+ return Poll::Ready(Err(std::io::Error::new(
458
+ std::io::ErrorKind::BrokenPipe,
459
+ "PipeRx is closed",
460
+ )));
461
+ };
462
+
463
+ let mut rx = rx.lock().unwrap();
464
+ loop {
465
+ if Self::try_read_from_buffer(&mut rx, buf.remaining(), |read_buf| {
466
+ buf.put_slice(read_buf);
467
+ Some(read_buf.len())
468
+ })
469
+ .is_some()
470
+ {
471
+ return Poll::Ready(Ok(()));
472
+ }
473
+
474
+ let data = match rx.chan.poll_recv(cx) {
475
+ Poll::Ready(Some(a)) => a,
476
+ Poll::Ready(None) => return Poll::Ready(Ok(())),
477
+ Poll::Pending => return Poll::Pending,
478
+ };
479
+
480
+ rx.buffer.replace(Bytes::from(data));
481
+ }
482
+ }
483
+ }
484
+
485
+ impl VirtualFile for Pipe {
486
+ /// the last time the file was accessed in nanoseconds as a UNIX timestamp
487
+ fn last_accessed(&self) -> u64 {
488
+ 0
489
+ }
490
+
491
+ /// the last time the file was modified in nanoseconds as a UNIX timestamp
492
+ fn last_modified(&self) -> u64 {
493
+ 0
494
+ }
495
+
496
+ /// the time at which the file was created in nanoseconds as a UNIX timestamp
497
+ fn created_time(&self) -> u64 {
498
+ 0
499
+ }
500
+
501
+ /// the size of the file in bytes
502
+ fn size(&self) -> u64 {
503
+ 0
504
+ }
505
+
506
+ /// Change the size of the file, if the `new_size` is greater than the current size
507
+ /// the extra bytes will be allocated and zeroed
508
+ fn set_len(&mut self, _new_size: u64) -> crate::Result<()> {
509
+ Ok(())
510
+ }
511
+
512
+ /// Request deletion of the file
513
+ fn unlink(&mut self) -> Result<(), FsError> {
514
+ Ok(())
515
+ }
516
+
517
+ /// Indicates if the file is opened or closed. This function must not block
518
+ /// Defaults to a status of being constantly open
519
+ fn is_open(&self) -> bool {
520
+ self.send
521
+ .tx
522
+ .as_ref()
523
+ .map(|a| !a.is_closed())
524
+ .unwrap_or_else(|| false)
525
+ }
526
+
527
+ /// Polls the file for when there is data to be read
528
+ fn poll_read_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
529
+ Pin::new(&mut self.recv).poll_read_ready(cx)
530
+ }
531
+
532
+ /// Polls the file for when it is available for writing
533
+ fn poll_write_ready(
534
+ mut self: Pin<&mut Self>,
535
+ _cx: &mut Context<'_>,
536
+ ) -> Poll<io::Result<usize>> {
537
+ Pin::new(&mut self.send).poll_write_ready()
538
+ }
539
+ }
540
+
541
+ /// A pair of pipes that are connected together.
542
+ #[derive(Clone, Debug)]
543
+ pub struct DuplexPipe {
544
+ front: Pipe,
545
+ back: Pipe,
546
+ }
547
+
548
+ impl DuplexPipe {
549
+ /// Get the sender pipe.
550
+ pub fn front(&self) -> &Pipe {
551
+ &self.front
552
+ }
553
+
554
+ /// Get the receiver pipe.
555
+ pub fn back(&self) -> &Pipe {
556
+ &self.back
557
+ }
558
+
559
+ /// Get the mutable sender pipe.
560
+ pub fn front_mut(&mut self) -> &mut Pipe {
561
+ &mut self.front
562
+ }
563
+
564
+ /// Get the receiver pipe.
565
+ pub fn back_mut(&mut self) -> &mut Pipe {
566
+ &mut self.back
567
+ }
568
+
569
+ /// Split into two pipes that are connected to each other
570
+ pub fn split(self) -> (Pipe, Pipe) {
571
+ (self.front, self.back)
572
+ }
573
+
574
+ /// Combines two ends of a duplex pipe back together again
575
+ pub fn combine(front: Pipe, back: Pipe) -> Self {
576
+ Self { front, back }
577
+ }
578
+
579
+ pub fn reverse(self) -> Self {
580
+ let (front, back) = self.split();
581
+ Self::combine(back, front)
582
+ }
583
+ }
584
+
585
+ impl Default for DuplexPipe {
586
+ fn default() -> Self {
587
+ Self::new()
588
+ }
589
+ }
590
+
591
+ impl DuplexPipe {
592
+ pub fn new() -> DuplexPipe {
593
+ let (end1, end2) = Pipe::channel();
594
+ Self {
595
+ front: end1,
596
+ back: end2,
597
+ }
598
+ }
599
+ }
600
+
601
+ /// Shared version of BidiPipe for situations where you need
602
+ /// to emulate the old behaviour of `Pipe` (both send and recv on one channel).
603
+ pub type WasiBidirectionalSharedPipePair = ArcFile<DuplexPipe>;