Skip to content

Commit 0a3c7bc

Browse files
authored
FF WASI submodule and update the machinery (#42)
* FF WASI submodule and update the machinery This commit fast-forwards the `WASI` submodule and updates the relevant the machinery. It also updates `generate_raw::generate` fn to accept a slice in preparation for multi-module `wasi_ephemeral`. * Fix generating wasi-ephemeral * Account for reserved keywords as func names * Preserve to_snake_case for func names * Feature-gate wrapper syscall gen for ephemeral * Handle IntDatatype
1 parent 4582e7d commit 0a3c7bc

File tree

8 files changed

+113
-50
lines changed

8 files changed

+113
-50
lines changed

crates/generate-raw/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ edition = "2018"
99
[dependencies]
1010
heck = "0.3"
1111
witx = { path = "WASI/tools/witx" }
12+
cfg-if = "0.1"
13+
14+
[features]
15+
default = []
16+
multi-module = []

crates/generate-raw/WASI

Submodule WASI updated 44 files

crates/generate-raw/src/lib.rs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::path::Path;
44
use std::process::{Command, Stdio};
55
use witx::*;
66

7-
pub fn generate(witx_path: &Path) -> String {
8-
let doc = witx::load(&[witx_path]).unwrap();
7+
pub fn generate<P: AsRef<Path>>(witx_paths: &[P]) -> String {
8+
let doc = witx::load(witx_paths).unwrap();
99

1010
let mut raw = String::new();
1111
raw.push_str(
@@ -59,23 +59,41 @@ trait Render {
5959
impl Render for NamedType {
6060
fn render(&self, src: &mut String) {
6161
let name = self.name.as_str();
62-
match &self.dt {
62+
match &self.tref {
6363
TypeRef::Value(ty) => match &**ty {
6464
Type::Enum(e) => render_enum(src, name, e),
6565
Type::Flags(f) => render_flags(src, name, f),
66+
Type::Int(c) => render_const(src, name, c),
6667
Type::Struct(s) => render_struct(src, name, s),
6768
Type::Union(u) => render_union(src, name, u),
6869
Type::Handle(h) => render_handle(src, name, h),
6970
Type::Array { .. }
7071
| Type::Pointer { .. }
7172
| Type::ConstPointer { .. }
72-
| Type::Builtin { .. } => render_alias(src, name, &self.dt),
73+
| Type::Builtin { .. } => render_alias(src, name, &self.tref),
7374
},
74-
TypeRef::Name(_nt) => render_alias(src, name, &self.dt),
75+
TypeRef::Name(_nt) => render_alias(src, name, &self.tref),
7576
}
7677
}
7778
}
7879

80+
// TODO verify this is correct way of handling IntDatatype
81+
fn render_const(src: &mut String, name: &str, c: &IntDatatype) {
82+
src.push_str(&format!("pub type {} = ", name.to_camel_case()));
83+
c.repr.render(src);
84+
src.push_str(";\n");
85+
for r#const in c.consts.iter() {
86+
rustdoc(&r#const.docs, src);
87+
src.push_str(&format!(
88+
"pub const {}_{}: {} = {};",
89+
name.to_shouty_snake_case(),
90+
r#const.name.as_str().to_shouty_snake_case(),
91+
name.to_camel_case(),
92+
r#const.value
93+
));
94+
}
95+
}
96+
7997
fn render_union(src: &mut String, name: &str, u: &UnionDatatype) {
8098
src.push_str("#[repr(C)]\n");
8199
src.push_str("#[derive(Copy, Clone)]\n");
@@ -223,6 +241,14 @@ impl Render for BuiltinType {
223241
BuiltinType::S64 => src.push_str("i64"),
224242
BuiltinType::F32 => src.push_str("f32"),
225243
BuiltinType::F64 => src.push_str("f64"),
244+
BuiltinType::USize => {
245+
// TODO verify handling of USize
246+
src.push_str("usize")
247+
}
248+
BuiltinType::Char8 => {
249+
// TODO verify handling of Char8
250+
src.push_str("char")
251+
}
226252
}
227253
}
228254
}
@@ -254,7 +280,9 @@ impl Render for Module {
254280
}
255281

256282
fn render_highlevel(func: &InterfaceFunc, module: &str, src: &mut String) {
257-
let rust_name = func.name.as_str().to_snake_case();
283+
let mut rust_name = String::new();
284+
func.name.render(&mut rust_name);
285+
let rust_name = rust_name.to_snake_case();
258286
rustdoc(&func.docs, src);
259287
rustdoc_params(&func.params, "Parameters", src);
260288
rustdoc_params(&func.results, "Return", src);
@@ -265,7 +293,18 @@ fn render_highlevel(func: &InterfaceFunc, module: &str, src: &mut String) {
265293
// descriptors, which are effectively forgeable and danglable raw pointers
266294
// into the file descriptor address space.
267295
src.push_str("pub unsafe fn ");
268-
src.push_str(&rust_name);
296+
297+
// TODO workout how to handle wasi-ephemeral which introduces multiple
298+
// WASI modules into the picture. For now, feature-gate it, and if we're
299+
// compiling ephmeral bindings, prefix wrapper syscall with module name.
300+
cfg_if::cfg_if! {
301+
if #[cfg(feature = "multi-module")] {
302+
src.push_str(&[module, &rust_name].join("_"));
303+
} else {
304+
src.push_str(&rust_name);
305+
}
306+
}
307+
269308
src.push_str("(");
270309
for param in func.params.iter() {
271310
param.name.render(src);
@@ -363,7 +402,9 @@ impl Render for InterfaceFunc {
363402
src.push_str("\"]\n");
364403
}
365404
src.push_str("pub fn ");
366-
src.push_str(&self.name.as_str().to_snake_case());
405+
let mut name = String::new();
406+
self.name.render(&mut name);
407+
src.push_str(&name.to_snake_case());
367408
src.push_str("(");
368409
for param in self.params.iter() {
369410
param.render(src);
@@ -441,6 +482,7 @@ impl Render for Id {
441482
match self.as_str() {
442483
"in" => src.push_str("r#in"),
443484
"type" => src.push_str("r#type"),
485+
"yield" => src.push_str("r#yield"),
444486
s => src.push_str(s),
445487
}
446488
}

crates/generate-raw/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ use std::path::PathBuf;
44
fn main() {
55
let wasi_dir: PathBuf = env::args_os().nth(1).unwrap().into();
66
let witx_path = wasi_dir.join("phases/snapshot/witx/wasi_snapshot_preview1.witx");
7-
print!("{}", generate_raw::generate(&witx_path));
7+
print!("{}", generate_raw::generate(&[witx_path]));
88
}

crates/generate-raw/tests/verify.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
fn assert_same_as_src() {
33
let actual = include_str!("../../../src/lib_generated.rs");
44
let expected =
5-
generate_raw::generate("WASI/phases/snapshot/witx/wasi_snapshot_preview1.witx".as_ref());
5+
generate_raw::generate(&["WASI/phases/snapshot/witx/wasi_snapshot_preview1.witx"]);
66
if actual == expected {
77
return;
88
}

crates/wasi-ephemeral/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ keywords = ["webassembly", "wasm"]
1111
repository = "https://github.com/bytecodealliance/wasi"
1212

1313
[build-dependencies]
14-
generate-raw = { path = "../generate-raw" }
14+
generate-raw = { path = "../generate-raw", features = ["multi-module"] }
1515

1616
[features]
1717
default = ["std"]

crates/wasi-ephemeral/build.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
1-
use std::{env, fs::File, io::Write, path::PathBuf};
1+
use std::{
2+
env,
3+
fs::File,
4+
io::Write,
5+
path::{Path, PathBuf},
6+
};
7+
8+
const WITX_ROOT: &str = "../generate-raw/WASI/phases/ephemeral/witx";
9+
const WITX_MODULES: &[&str] = &[
10+
"args", "clock", "environ", "fd", "path", "poll", "proc", "random", "sched", "sock",
11+
];
212

313
fn main() {
414
let out_path: PathBuf = env::var_os("OUT_DIR").unwrap().into();
515
let mut f = File::create(out_path.join("lib_generated.rs")).unwrap();
6-
const WASI_EPHEMERAL_WITX: &str =
7-
"../generate-raw/WASI/phases/ephemeral/witx/wasi_ephemeral_preview.witx";
8-
let witx_path: PathBuf = env::var_os("WASI_EPHEMERAL_WITX")
9-
.unwrap_or_else(|| WASI_EPHEMERAL_WITX.into())
10-
.into();
11-
let out = generate_raw::generate(&witx_path);
16+
let root = Path::new(WITX_ROOT);
17+
let witx_paths: Vec<_> = WITX_MODULES
18+
.iter()
19+
.map(|x| {
20+
root.join(&["wasi_ephemeral_", x, ".witx"].join(""))
21+
.to_owned()
22+
})
23+
.collect();
24+
let out = generate_raw::generate(&witx_paths);
1225
write!(f, "{}", out).unwrap();
13-
println!("cargo:rerun-if-env-changed=WASI_EPHEMERAL_WITX");
14-
println!("cargo:rerun-if-changed={}", witx_path.display());
26+
for p in &witx_paths {
27+
println!("cargo:rerun-if-changed={}", p.display());
28+
}
1529
println!(
1630
"cargo:rerun-if-changed={}",
17-
witx_path.with_file_name("typenames.witx").display(),
31+
root.join("wasi_ephemeral_typenames.witx").display()
1832
);
1933
// TODO: Account for changes in use directives.
2034
}

src/lib_generated.rs

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ pub(crate) fn strerror(code: u16) -> &'static str {
262262
pub type Rights = u64;
263263
/// The right to invoke `fd_datasync`.
264264
/// If `path_open` is set, includes the right to invoke
265-
/// `path_open` with `fdflag::dsync`.
265+
/// `path_open` with `fdflags::dsync`.
266266
pub const RIGHTS_FD_DATASYNC: Rights = 0x1;
267267
/// The right to invoke `fd_read` and `sock_recv`.
268268
/// If `rights::fd_seek` is set, includes the right to invoke `fd_pread`.
@@ -273,10 +273,10 @@ pub const RIGHTS_FD_SEEK: Rights = 0x4;
273273
pub const RIGHTS_FD_FDSTAT_SET_FLAGS: Rights = 0x8;
274274
/// The right to invoke `fd_sync`.
275275
/// If `path_open` is set, includes the right to invoke
276-
/// `path_open` with `fdflag::rsync` and `fdflag::dsync`.
276+
/// `path_open` with `fdflags::rsync` and `fdflags::dsync`.
277277
pub const RIGHTS_FD_SYNC: Rights = 0x10;
278278
/// The right to invoke `fd_seek` in such a way that the file offset
279-
/// remains unaltered (i.e., `WHENCE_CUR` with offset zero), or to
279+
/// remains unaltered (i.e., `whence::cur` with offset zero), or to
280280
/// invoke `fd_tell`.
281281
pub const RIGHTS_FD_TELL: Rights = 0x20;
282282
/// The right to invoke `fd_write` and `sock_send`.
@@ -430,13 +430,13 @@ pub struct Fdstat {
430430
}
431431
pub type Device = u64;
432432
pub type Fstflags = u16;
433-
/// Adjust the last data access timestamp to the value stored in `filestat::st_atim`.
433+
/// Adjust the last data access timestamp to the value stored in `filestat::atim`.
434434
pub const FSTFLAGS_ATIM: Fstflags = 0x1;
435-
/// Adjust the last data access timestamp to the time of clock `clock::realtime`.
435+
/// Adjust the last data access timestamp to the time of clock `clockid::realtime`.
436436
pub const FSTFLAGS_ATIM_NOW: Fstflags = 0x2;
437-
/// Adjust the last data modification timestamp to the value stored in `filestat::st_mtim`.
437+
/// Adjust the last data modification timestamp to the value stored in `filestat::mtim`.
438438
pub const FSTFLAGS_MTIM: Fstflags = 0x4;
439-
/// Adjust the last data modification timestamp to the time of clock `clock::realtime`.
439+
/// Adjust the last data modification timestamp to the time of clock `clockid::realtime`.
440440
pub const FSTFLAGS_MTIM_NOW: Fstflags = 0x8;
441441
pub type Lookupflags = u32;
442442
/// As long as the resolved path corresponds to a symbolic link, it is expanded.
@@ -473,13 +473,13 @@ pub struct Filestat {
473473
}
474474
pub type Userdata = u64;
475475
pub type Eventtype = u8;
476-
/// The time value of clock `subscription::u.clock.clock_id` has
477-
/// reached timestamp `subscription::u.clock.timeout`.
476+
/// The time value of clock `subscription_clock::id` has
477+
/// reached timestamp `subscription_clock::timeout`.
478478
pub const EVENTTYPE_CLOCK: Eventtype = 0;
479-
/// File descriptor `subscription::u.fd_readwrite.fd` has data
479+
/// File descriptor `subscription_fd_readwrite::file_descriptor` has data
480480
/// available for reading. This event always triggers for regular files.
481481
pub const EVENTTYPE_FD_READ: Eventtype = 1;
482-
/// File descriptor `subscription::u.fd_readwrite.fd` has capacity
482+
/// File descriptor `subscription_fd_readwrite::file_descriptor` has capacity
483483
/// available for writing. This event always triggers for regular files.
484484
pub const EVENTTYPE_FD_WRITE: Eventtype = 2;
485485
pub type Eventrwflags = u16;
@@ -513,10 +513,10 @@ pub struct Event {
513513
}
514514
pub type Subclockflags = u16;
515515
/// If set, treat the timestamp provided in
516-
/// `subscription::u.clock.timeout` as an absolute timestamp of clock
517-
/// `subscription::u.clock.clock_id.` If clear, treat the timestamp
518-
/// provided in `subscription::u.clock.timeout` relative to the
519-
/// current time value of clock `subscription::u.clock.clock_id.`
516+
/// `subscription_clock::timeout` as an absolute timestamp of clock
517+
/// `subscription_clock::id`. If clear, treat the timestamp
518+
/// provided in `subscription_clock::timeout` relative to the
519+
/// current time value of clock `subscription_clock::id`.
520520
pub const SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME: Subclockflags = 0x1;
521521
#[repr(C)]
522522
#[derive(Copy, Clone)]
@@ -689,7 +689,7 @@ pub struct Prestat {
689689
pub u: PrestatU,
690690
}
691691
/// Read command-line argument data.
692-
/// The size of the array should match that returned by `wasi_args_sizes_get()`
692+
/// The size of the array should match that returned by `args_sizes_get`
693693
pub unsafe fn args_get(argv: *mut *mut u8, argv_buf: *mut u8) -> Result<()> {
694694
let rc = wasi_snapshot_preview1::args_get(argv, argv_buf);
695695
if let Some(err) = Error::from_raw_error(rc) {
@@ -717,7 +717,7 @@ pub unsafe fn args_sizes_get() -> Result<(Size, Size)> {
717717
}
718718

719719
/// Read environment variable data.
720-
/// The sizes of the buffers should match that returned by `environ.sizes_get()`.
720+
/// The sizes of the buffers should match that returned by `environ_sizes_get`.
721721
pub unsafe fn environ_get(environ: *mut *mut u8, environ_buf: *mut u8) -> Result<()> {
722722
let rc = wasi_snapshot_preview1::environ_get(environ, environ_buf);
723723
if let Some(err) = Error::from_raw_error(rc) {
@@ -746,7 +746,8 @@ pub unsafe fn environ_sizes_get() -> Result<(Size, Size)> {
746746
}
747747

748748
/// Return the resolution of a clock.
749-
/// Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL`
749+
/// Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
750+
/// return `errno::inval`.
750751
/// Note: This is similar to `clock_getres` in POSIX.
751752
///
752753
/// ## Parameters
@@ -874,7 +875,7 @@ pub unsafe fn fd_fdstat_set_flags(fd: Fd, flags: Fdflags) -> Result<()> {
874875
}
875876

876877
/// Adjust the rights associated with a file descriptor.
877-
/// This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights
878+
/// This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
878879
///
879880
/// ## Parameters
880881
///
@@ -1279,7 +1280,7 @@ pub unsafe fn path_link(
12791280
///
12801281
/// * `dirflags` - Flags determining the method of how the path is resolved.
12811282
/// * `path` - The relative path of the file or directory to open, relative to the
1282-
/// `dirfd` directory.
1283+
/// `path_open::fd` directory.
12831284
/// * `oflags` - The method by which to open the file.
12841285
/// * `fs_rights_base` - The initial rights of the newly created file descriptor. The
12851286
/// implementation is allowed to return a file descriptor with fewer rights
@@ -1349,7 +1350,7 @@ pub unsafe fn path_readlink(fd: Fd, path: &str, buf: *mut u8, buf_len: Size) ->
13491350
}
13501351

13511352
/// Remove a directory.
1352-
/// Return `ENOTEMPTY` if the directory is not empty.
1353+
/// Return `errno::notempty` if the directory is not empty.
13531354
/// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
13541355
///
13551356
/// ## Parameters
@@ -1411,7 +1412,7 @@ pub unsafe fn path_symlink(old_path: &str, fd: Fd, new_path: &str) -> Result<()>
14111412
}
14121413

14131414
/// Unlink a file.
1414-
/// Return `EISDIR` if the path refers to a directory.
1415+
/// Return `errno::isdir` if the path refers to a directory.
14151416
/// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
14161417
///
14171418
/// ## Parameters
@@ -1586,17 +1587,18 @@ pub mod wasi_snapshot_preview1 {
15861587
#[link(wasm_import_module = "wasi_snapshot_preview1")]
15871588
extern "C" {
15881589
/// Read command-line argument data.
1589-
/// The size of the array should match that returned by `wasi_args_sizes_get()`
1590+
/// The size of the array should match that returned by `args_sizes_get`
15901591
pub fn args_get(argv: *mut *mut u8, argv_buf: *mut u8) -> Errno;
15911592
/// Return command-line argument data sizes.
15921593
pub fn args_sizes_get(argc: *mut Size, argv_buf_size: *mut Size) -> Errno;
15931594
/// Read environment variable data.
1594-
/// The sizes of the buffers should match that returned by `environ.sizes_get()`.
1595+
/// The sizes of the buffers should match that returned by `environ_sizes_get`.
15951596
pub fn environ_get(environ: *mut *mut u8, environ_buf: *mut u8) -> Errno;
15961597
/// Return command-line argument data sizes.
15971598
pub fn environ_sizes_get(argc: *mut Size, argv_buf_size: *mut Size) -> Errno;
15981599
/// Return the resolution of a clock.
1599-
/// Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks, return `WASI_EINVAL`
1600+
/// Implementations are required to provide a non-zero value for supported clocks. For unsupported clocks,
1601+
/// return `errno::inval`.
16001602
/// Note: This is similar to `clock_getres` in POSIX.
16011603
pub fn clock_res_get(id: Clockid, resolution: *mut Timestamp) -> Errno;
16021604
/// Return the time value of a clock.
@@ -1621,7 +1623,7 @@ pub mod wasi_snapshot_preview1 {
16211623
/// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
16221624
pub fn fd_fdstat_set_flags(fd: Fd, flags: Fdflags) -> Errno;
16231625
/// Adjust the rights associated with a file descriptor.
1624-
/// This can only be used to remove rights, and returns `ENOTCAPABLE` if called in a way that would attempt to add rights
1626+
/// This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
16251627
pub fn fd_fdstat_set_rights(
16261628
fd: Fd,
16271629
fs_rights_base: Rights,
@@ -1775,7 +1777,7 @@ pub mod wasi_snapshot_preview1 {
17751777
bufused: *mut Size,
17761778
) -> Errno;
17771779
/// Remove a directory.
1778-
/// Return `ENOTEMPTY` if the directory is not empty.
1780+
/// Return `errno::notempty` if the directory is not empty.
17791781
/// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
17801782
pub fn path_remove_directory(fd: Fd, path_ptr: *const u8, path_len: usize) -> Errno;
17811783
/// Rename a file or directory.
@@ -1798,7 +1800,7 @@ pub mod wasi_snapshot_preview1 {
17981800
new_path_len: usize,
17991801
) -> Errno;
18001802
/// Unlink a file.
1801-
/// Return `EISDIR` if the path refers to a directory.
1803+
/// Return `errno::isdir` if the path refers to a directory.
18021804
/// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
18031805
pub fn path_unlink_file(fd: Fd, path_ptr: *const u8, path_len: usize) -> Errno;
18041806
/// Concurrently poll for the occurrence of a set of events.

0 commit comments

Comments
 (0)