port in args and env. slightly different style
building up a bunch of deferred errors in the CtxBuilder sucks. so does reporting errors right away. Idk what to do here?
This commit is contained in:
@@ -25,7 +25,7 @@ pub fn instantiate(
|
|||||||
// Additionally register any preopened directories if we have them.
|
// Additionally register any preopened directories if we have them.
|
||||||
let mut builder = wasi_c2::WasiCtx::builder();
|
let mut builder = wasi_c2::WasiCtx::builder();
|
||||||
|
|
||||||
builder.arg(bin_name).arg(".").inherit_stdio();
|
builder.arg(bin_name)?.arg(".")?.inherit_stdio();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if let Some(workspace) = workspace {
|
if let Some(workspace) = workspace {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::dir::{DirCaps, DirEntry, WasiDir};
|
use crate::dir::{DirCaps, DirEntry, WasiDir};
|
||||||
use crate::file::{FileCaps, FileEntry, WasiFile};
|
use crate::file::{FileCaps, FileEntry, WasiFile};
|
||||||
|
use crate::string_array::{StringArray, StringArrayError};
|
||||||
use crate::table::Table;
|
use crate::table::Table;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
@@ -7,6 +8,8 @@ use std::path::PathBuf;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct WasiCtx {
|
pub struct WasiCtx {
|
||||||
|
pub(crate) args: StringArray,
|
||||||
|
pub(crate) env: StringArray,
|
||||||
table: Rc<RefCell<Table>>,
|
table: Rc<RefCell<Table>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,6 +20,8 @@ impl WasiCtx {
|
|||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
WasiCtx {
|
WasiCtx {
|
||||||
|
args: StringArray::new(),
|
||||||
|
env: StringArray::new(),
|
||||||
table: Rc::new(RefCell::new(Table::new())),
|
table: Rc::new(RefCell::new(Table::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,9 +69,9 @@ impl WasiCtxBuilder {
|
|||||||
pub fn build(self) -> Result<WasiCtx, Error> {
|
pub fn build(self) -> Result<WasiCtx, Error> {
|
||||||
Ok(self.0)
|
Ok(self.0)
|
||||||
}
|
}
|
||||||
pub fn arg(&mut self, _arg: &str) -> &mut Self {
|
pub fn arg(&mut self, arg: &str) -> Result<&mut Self, StringArrayError> {
|
||||||
// Intentionally left blank. We do not handle arguments yet.
|
self.0.args.push(arg.to_owned())?;
|
||||||
self
|
Ok(self)
|
||||||
}
|
}
|
||||||
pub fn inherit_stdio(&mut self) -> &mut Self {
|
pub fn inherit_stdio(&mut self) -> &mut Self {
|
||||||
self.0.insert_file(
|
self.0.insert_file(
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ mod error;
|
|||||||
mod file;
|
mod file;
|
||||||
pub mod snapshots;
|
pub mod snapshots;
|
||||||
pub mod stdio;
|
pub mod stdio;
|
||||||
|
mod string_array;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
|
|
||||||
pub use ctx::WasiCtx;
|
pub use ctx::WasiCtx;
|
||||||
pub use dir::{DirCaps, WasiDir};
|
pub use dir::{DirCaps, WasiDir};
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use file::{FileCaps, WasiFile};
|
pub use file::{FileCaps, WasiFile};
|
||||||
|
pub use string_array::StringArrayError;
|
||||||
|
|||||||
@@ -106,11 +106,11 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
argv: &GuestPtr<'b, GuestPtr<'b, u8>>,
|
argv: &GuestPtr<'b, GuestPtr<'b, u8>>,
|
||||||
argv_buf: &GuestPtr<'b, u8>,
|
argv_buf: &GuestPtr<'b, u8>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
unimplemented!()
|
self.args.write_to_guest(argv_buf, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn args_sizes_get(&self) -> Result<(types::Size, types::Size), Error> {
|
fn args_sizes_get(&self) -> Result<(types::Size, types::Size), Error> {
|
||||||
unimplemented!()
|
Ok((self.args.number_elements(), self.args.cumulative_size()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn environ_get<'b>(
|
fn environ_get<'b>(
|
||||||
@@ -118,11 +118,11 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
environ: &GuestPtr<'b, GuestPtr<'b, u8>>,
|
environ: &GuestPtr<'b, GuestPtr<'b, u8>>,
|
||||||
environ_buf: &GuestPtr<'b, u8>,
|
environ_buf: &GuestPtr<'b, u8>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
unimplemented!()
|
self.env.write_to_guest(environ_buf, environ)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn environ_sizes_get(&self) -> Result<(types::Size, types::Size), Error> {
|
fn environ_sizes_get(&self) -> Result<(types::Size, types::Size), Error> {
|
||||||
unimplemented!()
|
Ok((self.env.number_elements(), self.env.cumulative_size()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clock_res_get(&self, id: types::Clockid) -> Result<types::Timestamp, Error> {
|
fn clock_res_get(&self, id: types::Clockid) -> Result<types::Timestamp, Error> {
|
||||||
|
|||||||
71
crates/wasi-c2/src/string_array.rs
Normal file
71
crates/wasi-c2/src/string_array.rs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
use crate::Error;
|
||||||
|
use wiggle::GuestPtr;
|
||||||
|
|
||||||
|
pub struct StringArray {
|
||||||
|
elems: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum StringArrayError {
|
||||||
|
#[error("Number of elements exceeds 2^32")]
|
||||||
|
NumberElements,
|
||||||
|
#[error("Element size exceeds 2^32")]
|
||||||
|
ElementSize,
|
||||||
|
#[error("Cumulative size exceeds 2^32")]
|
||||||
|
CumulativeSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StringArray {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
StringArray { elems: Vec::new() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, elem: String) -> Result<(), StringArrayError> {
|
||||||
|
if self.elems.len() + 1 > std::u32::MAX as usize {
|
||||||
|
return Err(StringArrayError::NumberElements);
|
||||||
|
}
|
||||||
|
if elem.as_bytes().len() + 1 > std::u32::MAX as usize {
|
||||||
|
return Err(StringArrayError::ElementSize);
|
||||||
|
}
|
||||||
|
if self.cumulative_size() as usize + elem.as_bytes().len() + 1 > std::u32::MAX as usize {
|
||||||
|
return Err(StringArrayError::CumulativeSize);
|
||||||
|
}
|
||||||
|
self.elems.push(elem);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn number_elements(&self) -> u32 {
|
||||||
|
self.elems.len() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cumulative_size(&self) -> u32 {
|
||||||
|
self.elems
|
||||||
|
.iter()
|
||||||
|
.map(|e| e.as_bytes().len() + 1)
|
||||||
|
.sum::<usize>() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_to_guest<'a>(
|
||||||
|
&self,
|
||||||
|
buffer: &GuestPtr<'a, u8>,
|
||||||
|
element_heads: &GuestPtr<'a, GuestPtr<'a, u8>>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let element_heads = element_heads.as_array(self.number_elements());
|
||||||
|
let buffer = buffer.as_array(self.cumulative_size());
|
||||||
|
let mut cursor = 0;
|
||||||
|
for (elem, head) in self.elems.iter().zip(element_heads.iter()) {
|
||||||
|
let bytes = elem.as_bytes();
|
||||||
|
let len = bytes.len() as u32;
|
||||||
|
{
|
||||||
|
let elem_buffer = buffer
|
||||||
|
.get_range(cursor..(cursor + len))
|
||||||
|
.ok_or(Error::Inval)?; // Elements don't fit in buffer provided
|
||||||
|
elem_buffer.copy_from_slice(bytes)?;
|
||||||
|
}
|
||||||
|
buffer.get(cursor + len).ok_or(Error::Inval)?.write(0)?; // 0 terminate
|
||||||
|
head?.write(buffer.get(cursor).expect("already validated"))?;
|
||||||
|
cursor += len + 1;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user