feat(wasm-backend, app-service)!: use String for wasi env vars + require Clone for Function trait (#333)

* use String instead of Vec<u8> for wasi envs

* require Clone for Function trait

* fmt

* pr fixes
This commit is contained in:
Valery Antopol
2023-06-14 17:47:14 +03:00
committed by GitHub
parent 1e6dc4aca6
commit aeae703229
9 changed files with 23 additions and 45 deletions

View File

@ -91,7 +91,7 @@ impl<WB: WasmBackend> MModuleConfig<WB> {
self
}
pub fn with_wasi_envs(mut self, envs: HashMap<Vec<u8>, Vec<u8>>) -> Self {
pub fn with_wasi_envs(mut self, envs: HashMap<String, String>) -> Self {
self.wasi_parameters.envs = envs;
self
}

View File

@ -45,7 +45,7 @@ pub struct AppService {
impl AppService {
/// Create Service with given modules and service id.
pub fn new<C, S>(config: C, service_id: S, envs: HashMap<Vec<u8>, Vec<u8>>) -> Result<Self>
pub fn new<C, S>(config: C, service_id: S, envs: HashMap<String, String>) -> Result<Self>
where
C: TryInto<AppServiceConfig>,
S: Into<String>,
@ -134,7 +134,7 @@ impl AppService {
fn set_env_and_dirs(
config: &mut AppServiceConfig,
service_id: String,
mut envs: HashMap<Vec<u8>, Vec<u8>>,
mut envs: HashMap<String, String>,
) -> Result<()> {
let working_dir = &config.service_working_dir;
let root_tmp_dir = &config.service_base_dir.join(&service_id);
@ -156,10 +156,7 @@ impl AppService {
format!("/{SERVICE_TMP_DIR_NAME}") => service_tmp_dir,
};
envs.insert(
SERVICE_ID_ENV_NAME.as_bytes().to_vec(),
service_id.into_bytes(),
);
envs.insert(SERVICE_ID_ENV_NAME.to_string(), service_id);
for module in &mut config.marine_config.modules_config {
module.config.extend_wasi_envs(envs.clone());
@ -191,7 +188,7 @@ impl AppService {
pub fn new_with_empty_facade<C, S>(
config: C,
service_id: S,
envs: HashMap<Vec<u8>, Vec<u8>>,
envs: HashMap<String, String>,
) -> Result<Self>
where
S: Into<String>,

View File

@ -21,6 +21,7 @@ use crate::DelayedContextLifetime;
use crate::WasmBackend;
/// Contains Wasm exports necessary for internal usage.
#[derive(Clone)]
pub enum Export<WB: WasmBackend> {
Memory(<WB as WasmBackend>::Memory),
Function(<WB as WasmBackend>::Function),

View File

@ -23,7 +23,7 @@ use crate::WValue;
/// A Wasm function handle, it can be either a function from a host or an export from an `Instance`.
/// As it is only a handle to an object in `Store`, cloning is cheap
pub trait Function<WB: WasmBackend>: Send + Sync {
pub trait Function<WB: WasmBackend>: Send + Sync + Clone {
/// Creates a new function with dynamic signature.
/// The signature check is performed at runtime.
fn new<F>(store: &mut impl AsContextMut<WB>, sig: FuncSig, func: F) -> Self

View File

@ -41,8 +41,8 @@ pub trait WasiImplementation<WB: WasmBackend> {
#[derive(Default)]
pub struct WasiParameters {
pub args: Vec<Vec<u8>>,
pub envs: HashMap<Vec<u8>, Vec<u8>>,
pub args: Vec<String>,
pub envs: HashMap<String, String>,
pub preopened_files: HashSet<PathBuf>,
pub mapped_dirs: HashMap<String, PathBuf>,
}

View File

@ -30,6 +30,7 @@ use marine_wasm_backend_traits::replace_with;
use anyhow::anyhow;
#[derive(Clone)]
pub struct WasmtimeFunction {
pub(crate) inner: wasmtime::Func,
}

View File

@ -97,12 +97,7 @@ fn add_wasi_to_linker(
Ok(())
}
fn populate_args(builder: WasiCtxBuilder, args: Vec<Vec<u8>>) -> Result<WasiCtxBuilder, WasiError> {
let args = args
.into_iter()
.map(|arg| unsafe { String::from_utf8_unchecked(arg) })
.collect::<Vec<String>>();
fn populate_args(builder: WasiCtxBuilder, args: Vec<String>) -> Result<WasiCtxBuilder, WasiError> {
builder
.args(&args)
.map_err(|_| WasiError::TooLargeArgsArray)
@ -140,20 +135,9 @@ fn populate_mapped_dirs(
fn populate_envs(
builder: WasiCtxBuilder,
envs: HashMap<Vec<u8>, Vec<u8>>,
envs: HashMap<String, String>,
) -> Result<WasiCtxBuilder, WasiError> {
let envs = envs
.into_iter()
.map(|(key, value)| {
unsafe {
// TODO maybe use strings in signature?
(
String::from_utf8_unchecked(key),
String::from_utf8_unchecked(value),
)
}
})
.collect::<Vec<_>>();
let envs = envs.into_iter().collect::<Vec<_>>();
builder
.envs(&envs)

View File

@ -108,7 +108,7 @@ pub struct MarineModuleConfig<WB: WasmBackend> {
}
impl<WB: WasmBackend> MarineModuleConfig<WB> {
pub fn extend_wasi_envs(&mut self, new_envs: HashMap<Vec<u8>, Vec<u8>>) {
pub fn extend_wasi_envs(&mut self, new_envs: HashMap<String, String>) {
match &mut self.wasi {
Some(MarineWASIConfig { envs, .. }) => envs.extend(new_envs),
w @ None => {
@ -174,7 +174,7 @@ impl<WB: WasmBackend> MarineModuleConfig<WB> {
#[derive(Debug, Clone, Default)]
pub struct MarineWASIConfig {
/// A list of environment variables available for this module.
pub envs: HashMap<Vec<u8>, Vec<u8>>,
pub envs: HashMap<String, String>,
/// A list of files available for this module.
/// A loaded module could have access only to files from this list.
@ -303,12 +303,12 @@ impl TryFrom<TomlWASIConfig> for MarineWASIConfig {
type Error = MarineError;
fn try_from(toml_config: TomlWASIConfig) -> Result<Self, Self::Error> {
let to_vec = |elem: (String, toml::Value)| -> Result<(Vec<u8>, Vec<u8>), Self::Error> {
let to_string = |elem: (String, toml::Value)| -> Result<(String, String), Self::Error> {
let to = elem
.1
.try_into::<String>()
.map_err(MarineError::ParseConfigError)?;
Ok((elem.0.into_bytes(), to.into_bytes()))
Ok((elem.0, to))
};
// Makes sure that no user-defined paths can be safely placed in an isolated directory
@ -344,7 +344,7 @@ impl TryFrom<TomlWASIConfig> for MarineWASIConfig {
let envs = toml_config.envs.unwrap_or_default();
let envs = envs
.into_iter()
.map(to_vec)
.map(to_string)
.collect::<Result<HashMap<_, _>, _>>()?;
let preopened_files = toml_config.preopened_files.unwrap_or_default();

View File

@ -116,12 +116,7 @@ impl<WB: WasmBackend> MModuleConfigBuilder<WB> {
.wasi_parameters
.mapped_dirs
.iter()
.map(|(from, to)| {
(
from.as_bytes().to_vec(),
to.to_string_lossy().as_bytes().to_vec(),
)
})
.map(|(from, to)| (from.clone(), to.to_string_lossy().to_string()))
.collect::<HashMap<_, _>>();
self.config.wasi_parameters.envs.extend(mapped_dirs);
@ -187,10 +182,10 @@ impl<WB: WasmBackend> MModuleConfigBuilder<WB> {
};
// overwrite possibly installed log variable in config
self.config.wasi_parameters.envs.insert(
WASM_LOG_ENV_NAME.as_bytes().to_owned(),
log_level_str.into_bytes(),
);
self.config
.wasi_parameters
.envs
.insert(WASM_LOG_ENV_NAME.to_string(), log_level_str);
}
let creator = move |mut store: <WB as WasmBackend>::ContextMut<'_>| {