Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit 6e90903

Browse files
authored
Merge pull request #164 from bytecodealliance/pch/table_error
wasi-common: Table operations return a distinct TableError enum
2 parents bba1b8b + 1c95953 commit 6e90903

File tree

10 files changed

+78
-63
lines changed

10 files changed

+78
-63
lines changed

wasi-common/src/dir.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::file::{FdFlags, FileType, Filestat, OFlags, ReadOnlyFile, WasiFile};
2-
use crate::{Error, ErrorExt, SystemTimeSpec};
2+
use crate::{Error, ErrorExt, SystemTimeSpec, TableError};
33
use std::any::Any;
44
use std::path::PathBuf;
55

@@ -104,11 +104,11 @@ pub trait WasiDir: Send + Sync {
104104
}
105105

106106
pub trait TableDirExt {
107-
fn get_dir(&self, fd: u32) -> Result<&Box<dyn WasiDir>, Error>;
107+
fn get_dir(&self, fd: u32) -> Result<&Box<dyn WasiDir>, TableError>;
108108
}
109109

110110
impl TableDirExt for crate::table::Table {
111-
fn get_dir(&self, fd: u32) -> Result<&Box<dyn WasiDir>, Error> {
111+
fn get_dir(&self, fd: u32) -> Result<&Box<dyn WasiDir>, TableError> {
112112
self.get(fd)
113113
}
114114
}

wasi-common/src/file.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Error, ErrorExt, InputStream, OutputStream, SystemTimeSpec};
1+
use crate::{Error, ErrorExt, InputStream, OutputStream, SystemTimeSpec, TableError};
22
use bitflags::bitflags;
33
use std::any::Any;
44
use std::io;
@@ -163,14 +163,14 @@ pub struct Filestat {
163163
}
164164

165165
pub trait TableFileExt {
166-
fn get_file(&self, fd: u32) -> Result<&dyn WasiFile, Error>;
167-
fn get_file_mut(&mut self, fd: u32) -> Result<&mut Box<dyn WasiFile>, Error>;
166+
fn get_file(&self, fd: u32) -> Result<&dyn WasiFile, TableError>;
167+
fn get_file_mut(&mut self, fd: u32) -> Result<&mut Box<dyn WasiFile>, TableError>;
168168
}
169169
impl TableFileExt for crate::table::Table {
170-
fn get_file(&self, fd: u32) -> Result<&dyn WasiFile, Error> {
170+
fn get_file(&self, fd: u32) -> Result<&dyn WasiFile, TableError> {
171171
self.get::<Box<dyn WasiFile>>(fd).map(|f| f.as_ref())
172172
}
173-
fn get_file_mut(&mut self, fd: u32) -> Result<&mut Box<dyn WasiFile>, Error> {
173+
fn get_file_mut(&mut self, fd: u32) -> Result<&mut Box<dyn WasiFile>, TableError> {
174174
self.get_mut::<Box<dyn WasiFile>>(fd)
175175
}
176176
}

wasi-common/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,4 @@ pub use error::{Errno, Error, ErrorExt, I32Exit};
7373
pub use file::WasiFile;
7474
pub use sched::{Poll, WasiSched};
7575
pub use stream::{InputStream, OutputStream};
76-
pub use table::Table;
76+
pub use table::{Table, TableError};

wasi-common/src/preview2/filesystem.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ impl From<crate::Error> for wasi::filesystem::Error {
7575
}
7676
}
7777

78+
impl From<crate::TableError> for wasi::filesystem::Error {
79+
fn from(error: crate::TableError) -> wasi::filesystem::Error {
80+
match error {
81+
crate::TableError::Full => wasi::filesystem::Error::trap(anyhow!(error)),
82+
crate::TableError::NotPresent | crate::TableError::WrongType => {
83+
wasi::filesystem::ErrorCode::BadDescriptor.into()
84+
}
85+
}
86+
}
87+
}
88+
7889
impl From<wasi::filesystem::OpenFlags> for crate::file::OFlags {
7990
fn from(oflags: wasi::filesystem::OpenFlags) -> Self {
8091
let mut flags = crate::file::OFlags::empty();

wasi-common/src/preview2/io.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ impl From<crate::Error> for streams::Error {
1717
}
1818
}
1919

20+
impl From<crate::TableError> for streams::Error {
21+
fn from(error: crate::TableError) -> streams::Error {
22+
match error {
23+
crate::TableError::Full => streams::Error::trap(anyhow!(error)),
24+
crate::TableError::NotPresent | crate::TableError::WrongType => {
25+
// wit definition needs to define a badf-equiv variant:
26+
streams::StreamError {}.into()
27+
}
28+
}
29+
}
30+
}
31+
2032
#[async_trait::async_trait]
2133
impl<T: WasiView> streams::Host for T {
2234
async fn drop_input_stream(&mut self, stream: InputStream) -> anyhow::Result<()> {

wasi-common/src/preview2/poll.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,10 @@ use crate::{
33
wasi,
44
wasi::monotonic_clock::Instant,
55
wasi::poll::Pollable,
6-
wasi::streams::{InputStream, OutputStream, StreamError},
6+
wasi::streams::{InputStream, OutputStream},
77
WasiView,
88
};
99

10-
fn convert(error: crate::Error) -> anyhow::Error {
11-
if let Some(_errno) = error.downcast_ref() {
12-
anyhow::Error::new(StreamError {})
13-
} else {
14-
error.into()
15-
}
16-
}
17-
1810
/// A pollable resource table entry.
1911
#[derive(Copy, Clone)]
2012
pub(crate) enum PollableEntry {
@@ -39,9 +31,7 @@ pub(crate) enum PollableEntry {
3931
#[async_trait::async_trait]
4032
impl<T: WasiView> wasi::poll::Host for T {
4133
async fn drop_pollable(&mut self, pollable: Pollable) -> anyhow::Result<()> {
42-
self.table_mut()
43-
.delete::<PollableEntry>(pollable)
44-
.map_err(convert)?;
34+
self.table_mut().delete::<PollableEntry>(pollable)?;
4535
Ok(())
4636
}
4737

@@ -54,15 +44,15 @@ impl<T: WasiView> wasi::poll::Host for T {
5444
for (index, future) in futures.into_iter().enumerate() {
5545
let userdata = Userdata::from(index as u64);
5646

57-
match *self.table().get(future).map_err(convert)? {
47+
match *self.table().get(future)? {
5848
PollableEntry::Read(stream) => {
5949
let wasi_stream: &dyn crate::InputStream =
60-
self.table().get_input_stream(stream).map_err(convert)?;
50+
self.table().get_input_stream(stream)?;
6151
poll.subscribe_read(wasi_stream, userdata);
6252
}
6353
PollableEntry::Write(stream) => {
6454
let wasi_stream: &dyn crate::OutputStream =
65-
self.table().get_output_stream(stream).map_err(convert)?;
55+
self.table().get_output_stream(stream)?;
6656
poll.subscribe_write(wasi_stream, userdata);
6757
}
6858
PollableEntry::MonotonicClock(when, absolute) => {
@@ -75,7 +65,7 @@ impl<T: WasiView> wasi::poll::Host for T {
7565
} /*
7666
PollableEntry::TcpSocket(tcp_socket) => {
7767
let wasi_tcp_socket: &dyn crate::WasiTcpSocket =
78-
self.table().get_tcp_socket(tcp_socket).map_err(convert)?;
68+
self.table().get_tcp_socket(tcp_socket)?;
7969
poll.subscribe_tcp_socket(wasi_tcp_socket, userdata);
8070
}
8171
*/

wasi-common/src/stream.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Error, ErrorExt};
1+
use crate::{Error, ErrorExt, TableError};
22
use std::any::Any;
33

44
/// An input bytestream.
@@ -155,24 +155,24 @@ pub trait OutputStream: Send + Sync {
155155
}
156156

157157
pub trait TableStreamExt {
158-
fn get_input_stream(&self, fd: u32) -> Result<&dyn InputStream, Error>;
159-
fn get_input_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn InputStream>, Error>;
158+
fn get_input_stream(&self, fd: u32) -> Result<&dyn InputStream, TableError>;
159+
fn get_input_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn InputStream>, TableError>;
160160

161-
fn get_output_stream(&self, fd: u32) -> Result<&dyn OutputStream, Error>;
162-
fn get_output_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn OutputStream>, Error>;
161+
fn get_output_stream(&self, fd: u32) -> Result<&dyn OutputStream, TableError>;
162+
fn get_output_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn OutputStream>, TableError>;
163163
}
164164
impl TableStreamExt for crate::table::Table {
165-
fn get_input_stream(&self, fd: u32) -> Result<&dyn InputStream, Error> {
165+
fn get_input_stream(&self, fd: u32) -> Result<&dyn InputStream, TableError> {
166166
self.get::<Box<dyn InputStream>>(fd).map(|f| f.as_ref())
167167
}
168-
fn get_input_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn InputStream>, Error> {
168+
fn get_input_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn InputStream>, TableError> {
169169
self.get_mut::<Box<dyn InputStream>>(fd)
170170
}
171171

172-
fn get_output_stream(&self, fd: u32) -> Result<&dyn OutputStream, Error> {
172+
fn get_output_stream(&self, fd: u32) -> Result<&dyn OutputStream, TableError> {
173173
self.get::<Box<dyn OutputStream>>(fd).map(|f| f.as_ref())
174174
}
175-
fn get_output_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn OutputStream>, Error> {
175+
fn get_output_stream_mut(&mut self, fd: u32) -> Result<&mut Box<dyn OutputStream>, TableError> {
176176
self.get_mut::<Box<dyn OutputStream>>(fd)
177177
}
178178
}

wasi-common/src/table.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
use crate::{Error, ErrorExt};
21
use std::any::Any;
32
use std::collections::HashMap;
43

4+
#[derive(thiserror::Error, Debug)]
5+
pub enum TableError {
6+
#[error("table has no free keys")]
7+
Full,
8+
#[error("value not present")]
9+
NotPresent,
10+
#[error("value is of another type")]
11+
WrongType,
12+
}
13+
514
/// The `Table` type is designed to map u32 handles to resources. The table is now part of the
615
/// public interface to a `WasiCtx` - it is reference counted so that it can be shared beyond a
716
/// `WasiCtx` with other WASI proposals (e.g. `wasi-crypto` and `wasi-nn`) to manage their
@@ -24,11 +33,11 @@ impl Table {
2433
}
2534

2635
/// Insert a resource at the next available index.
27-
pub fn push(&mut self, a: Box<dyn Any + Send + Sync>) -> Result<u32, Error> {
36+
pub fn push(&mut self, a: Box<dyn Any + Send + Sync>) -> Result<u32, TableError> {
2837
// NOTE: The performance of this new key calculation could be very bad once keys wrap
2938
// around.
3039
if self.map.len() == u32::MAX as usize {
31-
return Err(Error::trap(anyhow::Error::msg("table has no free keys")));
40+
return Err(TableError::Full);
3241
}
3342
loop {
3443
let key = self.next_key;
@@ -41,25 +50,25 @@ impl Table {
4150
}
4251
}
4352

44-
pub fn push_file(&mut self, file: Box<dyn crate::WasiFile>) -> Result<u32, Error> {
53+
pub fn push_file(&mut self, file: Box<dyn crate::WasiFile>) -> Result<u32, TableError> {
4554
self.push(Box::new(file))
4655
}
4756

48-
pub fn push_dir(&mut self, dir: Box<dyn crate::WasiDir>) -> Result<u32, Error> {
57+
pub fn push_dir(&mut self, dir: Box<dyn crate::WasiDir>) -> Result<u32, TableError> {
4958
self.push(Box::new(dir))
5059
}
5160

5261
pub fn push_input_stream(
5362
&mut self,
5463
istream: Box<dyn crate::InputStream>,
55-
) -> Result<u32, Error> {
64+
) -> Result<u32, TableError> {
5665
self.push(Box::new(istream))
5766
}
5867

5968
pub fn push_output_stream(
6069
&mut self,
6170
ostream: Box<dyn crate::OutputStream>,
62-
) -> Result<u32, Error> {
71+
) -> Result<u32, TableError> {
6372
self.push(Box::new(ostream))
6473
}
6574

@@ -81,35 +90,33 @@ impl Table {
8190
/// Get an immutable reference to a resource of a given type at a given index. Multiple
8291
/// immutable references can be borrowed at any given time. Borrow failure
8392
/// results in a trapping error.
84-
pub fn get<T: Any + Sized>(&self, key: u32) -> Result<&T, Error> {
93+
pub fn get<T: Any + Sized>(&self, key: u32) -> Result<&T, TableError> {
8594
if let Some(r) = self.map.get(&key) {
86-
r.downcast_ref::<T>()
87-
.ok_or_else(|| Error::badf().context("element is a different type"))
95+
r.downcast_ref::<T>().ok_or_else(|| TableError::WrongType)
8896
} else {
89-
Err(Error::badf().context("key not in table"))
97+
Err(TableError::NotPresent)
9098
}
9199
}
92100

93101
/// Get a mutable reference to a resource of a given type at a given index. Only one mutable
94102
/// reference can be borrowed at any given time. Borrow failure results in a trapping error.
95-
pub fn get_mut<T: Any + Sized>(&mut self, key: u32) -> Result<&mut T, Error> {
103+
pub fn get_mut<T: Any + Sized>(&mut self, key: u32) -> Result<&mut T, TableError> {
96104
if let Some(r) = self.map.get_mut(&key) {
97-
r.downcast_mut::<T>()
98-
.ok_or_else(|| Error::badf().context("element is a different type"))
105+
r.downcast_mut::<T>().ok_or_else(|| TableError::WrongType)
99106
} else {
100-
Err(Error::badf().context("key not in table"))
107+
Err(TableError::NotPresent)
101108
}
102109
}
103110

104111
/// Remove a resource at a given index from the table. Returns the resource
105112
/// if it was present.
106-
pub fn delete<T: Any + Sized>(&mut self, key: u32) -> Result<Option<T>, Error> {
113+
pub fn delete<T: Any + Sized>(&mut self, key: u32) -> Result<Option<T>, TableError> {
107114
self.map
108115
.remove(&key)
109116
.map(|r| {
110117
r.downcast::<T>()
111118
.map(|r| *r)
112-
.map_err(|_| Error::badf().context("element is a different type"))
119+
.map_err(|_| TableError::WrongType)
113120
})
114121
.transpose()
115122
}

wasi-sockets/src/network_impl.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ use crate::{
55
};
66
use cap_std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
77

8-
pub(crate) fn convert(_error: wasi_common::Error) -> anyhow::Error {
9-
todo!("convert wasi-common Error to wasi_network::Error")
10-
}
11-
128
#[async_trait::async_trait]
139
impl<T: WasiSocketsView> network::Host for T {
1410
async fn drop_network(&mut self, this: Network) -> anyhow::Result<()> {
@@ -26,7 +22,7 @@ impl<T: WasiSocketsView> instance_network::Host for T {
2622
let ctx = self.ctx();
2723
let network = (ctx.network_creator)(ctx.pool.clone())?;
2824
let table = self.table_mut();
29-
let network = table.push(Box::new(network)).map_err(convert)?;
25+
let network = table.push(Box::new(network))?;
3026
Ok(network)
3127
}
3228
}

wasi-sockets/src/tcp.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
use crate::{
44
network::TableNetworkExt,
5-
network_impl::convert,
65
tcp_socket::TableTcpSocketExt,
76
wasi::network::{
87
Error, IpAddressFamily, Ipv4Address, Ipv4SocketAddress, Ipv6Address, Ipv6SocketAddress,
@@ -44,9 +43,9 @@ impl<T: WasiSocketsView> tcp::Host for T {
4443

4544
let (connection, input_stream, output_stream, _addr) = socket.accept(false).await?;
4645

47-
let connection = table.push(Box::new(connection)).map_err(convert)?;
48-
let input_stream = table.push(Box::new(input_stream)).map_err(convert)?;
49-
let output_stream = table.push(Box::new(output_stream)).map_err(convert)?;
46+
let connection = table.push(Box::new(connection))?;
47+
let input_stream = table.push(Box::new(input_stream))?;
48+
let output_stream = table.push(Box::new(output_stream))?;
5049

5150
Ok(Ok((connection, input_stream, output_stream)))
5251
}
@@ -63,8 +62,8 @@ impl<T: WasiSocketsView> tcp::Host for T {
6362

6463
let (input_stream, output_stream) = socket.connect(network, remote_address.into()).await?;
6564

66-
let input_stream = table.push(Box::new(input_stream)).map_err(convert)?;
67-
let output_stream = table.push(Box::new(output_stream)).map_err(convert)?;
65+
let input_stream = table.push(Box::new(input_stream))?;
66+
let output_stream = table.push(Box::new(output_stream))?;
6867

6968
Ok(Ok((input_stream, output_stream)))
7069
}
@@ -277,7 +276,7 @@ impl<T: WasiSocketsView> tcp_create_socket::Host for T {
277276
let ctx = self.ctx();
278277
let socket = (ctx.tcp_socket_creator)(address_family.into())?;
279278
let table = self.table_mut();
280-
let socket = table.push(Box::new(socket)).map_err(convert)?;
279+
let socket = table.push(Box::new(socket))?;
281280
Ok(Ok(socket))
282281
}
283282
}

0 commit comments

Comments
 (0)