integrate with c-api
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -3237,8 +3237,10 @@ name = "wasmtime-c-api"
|
|||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"cap-std",
|
||||||
"env_logger 0.8.2",
|
"env_logger 0.8.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"wasi-cap-std-sync",
|
||||||
"wasi-common",
|
"wasi-common",
|
||||||
"wasmtime",
|
"wasmtime",
|
||||||
"wasmtime-c-api-macros",
|
"wasmtime-c-api-macros",
|
||||||
|
|||||||
@@ -28,11 +28,13 @@ wat = { version = "1.0.23", optional = true }
|
|||||||
|
|
||||||
# Optional dependencies for the `wasi` feature
|
# Optional dependencies for the `wasi` feature
|
||||||
wasi-common = { path = "../wasi-common", optional = true }
|
wasi-common = { path = "../wasi-common", optional = true }
|
||||||
|
wasi-cap-std-sync = { path = "../wasi-common/cap-std-sync", optional = true }
|
||||||
wasmtime-wasi = { path = "../wasi", optional = true }
|
wasmtime-wasi = { path = "../wasi", optional = true }
|
||||||
|
cap-std = { version = "0.12", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ['jitdump', 'wat', 'wasi', 'cache']
|
default = ['jitdump', 'wat', 'wasi', 'cache']
|
||||||
lightbeam = ["wasmtime/lightbeam"]
|
lightbeam = ["wasmtime/lightbeam"]
|
||||||
jitdump = ["wasmtime/jitdump"]
|
jitdump = ["wasmtime/jitdump"]
|
||||||
cache = ["wasmtime/cache"]
|
cache = ["wasmtime/cache"]
|
||||||
wasi = ['wasi-common', 'wasmtime-wasi']
|
wasi = ['wasi-common', 'wasi-cap-std-sync', 'wasmtime-wasi', 'cap-std']
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
//! The WASI embedding API definitions for Wasmtime.
|
//! The WASI embedding API definitions for Wasmtime.
|
||||||
use crate::{wasm_extern_t, wasm_importtype_t, wasm_store_t, wasm_trap_t};
|
use crate::{wasm_extern_t, wasm_importtype_t, wasm_store_t, wasm_trap_t};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use cap_std::fs::Dir;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::rc::Rc;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::str;
|
use std::str;
|
||||||
use wasi_common::{preopen_dir, WasiCtx, WasiCtxBuilder};
|
use wasi_cap_std_sync::WasiCtxBuilder;
|
||||||
|
use wasi_common::WasiCtx;
|
||||||
use wasmtime::{Extern, Linker, Trap};
|
use wasmtime::{Extern, Linker, Trap};
|
||||||
use wasmtime_wasi::{old::snapshot_0::Wasi as WasiSnapshot0, Wasi as WasiPreview1};
|
use wasmtime_wasi::{
|
||||||
|
snapshots::preview_0::Wasi as WasiSnapshot0, snapshots::preview_1::Wasi as WasiPreview1,
|
||||||
|
};
|
||||||
|
|
||||||
unsafe fn cstr_to_path<'a>(path: *const c_char) -> Option<&'a Path> {
|
unsafe fn cstr_to_path<'a>(path: *const c_char) -> Option<&'a Path> {
|
||||||
CStr::from_ptr(path).to_str().map(Path::new).ok()
|
CStr::from_ptr(path).to_str().map(Path::new).ok()
|
||||||
@@ -39,7 +45,7 @@ pub struct wasi_config_t {
|
|||||||
stdin: Option<File>,
|
stdin: Option<File>,
|
||||||
stdout: Option<File>,
|
stdout: Option<File>,
|
||||||
stderr: Option<File>,
|
stderr: Option<File>,
|
||||||
preopens: Vec<(File, PathBuf)>,
|
preopens: Vec<(Dir, PathBuf)>,
|
||||||
inherit_args: bool,
|
inherit_args: bool,
|
||||||
inherit_env: bool,
|
inherit_env: bool,
|
||||||
inherit_stdin: bool,
|
inherit_stdin: bool,
|
||||||
@@ -180,7 +186,7 @@ pub unsafe extern "C" fn wasi_config_preopen_dir(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let dir = match cstr_to_path(path) {
|
let dir = match cstr_to_path(path) {
|
||||||
Some(p) => match preopen_dir(p) {
|
Some(p) => match cap_std::fs::Dir::open_ambient_dir(p) {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
},
|
},
|
||||||
@@ -197,39 +203,57 @@ enum WasiInstance {
|
|||||||
Snapshot0(WasiSnapshot0),
|
Snapshot0(WasiSnapshot0),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_wasi_ctx(config: wasi_config_t) -> Result<WasiCtx> {
|
fn create_wasi_ctx(config: wasi_config_t) -> Result<Rc<RefCell<WasiCtx>>> {
|
||||||
use std::convert::TryFrom;
|
|
||||||
use wasi_common::OsFile;
|
|
||||||
let mut builder = WasiCtxBuilder::new();
|
let mut builder = WasiCtxBuilder::new();
|
||||||
if config.inherit_args {
|
if config.inherit_args {
|
||||||
builder.inherit_args();
|
builder = builder.inherit_args()?;
|
||||||
} else if !config.args.is_empty() {
|
} else if !config.args.is_empty() {
|
||||||
builder.args(config.args);
|
let args = config
|
||||||
|
.args
|
||||||
|
.into_iter()
|
||||||
|
.map(|bytes| Ok(String::from_utf8(bytes)?))
|
||||||
|
.collect::<Result<Vec<String>>>()?;
|
||||||
|
builder = builder.args(&args)?;
|
||||||
}
|
}
|
||||||
if config.inherit_env {
|
if config.inherit_env {
|
||||||
builder.inherit_env();
|
builder = builder.inherit_env()?;
|
||||||
} else if !config.env.is_empty() {
|
} else if !config.env.is_empty() {
|
||||||
builder.envs(config.env);
|
let env = config
|
||||||
|
.env
|
||||||
|
.into_iter()
|
||||||
|
.map(|(kbytes, vbytes)| {
|
||||||
|
let k = String::from_utf8(kbytes)?;
|
||||||
|
let v = String::from_utf8(vbytes)?;
|
||||||
|
Ok((k, v))
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<(String, String)>>>()?;
|
||||||
|
builder = builder.envs(&env)?;
|
||||||
}
|
}
|
||||||
if config.inherit_stdin {
|
if config.inherit_stdin {
|
||||||
builder.inherit_stdin();
|
builder = builder.inherit_stdin();
|
||||||
} else if let Some(file) = config.stdin {
|
} else if let Some(file) = config.stdin {
|
||||||
builder.stdin(OsFile::try_from(file)?);
|
let file = unsafe { cap_std::fs::File::from_std(file) };
|
||||||
|
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
||||||
|
builder = builder.stdin(Box::new(file));
|
||||||
}
|
}
|
||||||
if config.inherit_stdout {
|
if config.inherit_stdout {
|
||||||
builder.inherit_stdout();
|
builder = builder.inherit_stdout();
|
||||||
} else if let Some(file) = config.stdout {
|
} else if let Some(file) = config.stdout {
|
||||||
builder.stdout(OsFile::try_from(file)?);
|
let file = unsafe { cap_std::fs::File::from_std(file) };
|
||||||
|
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
||||||
|
builder = builder.stdout(Box::new(file));
|
||||||
}
|
}
|
||||||
if config.inherit_stderr {
|
if config.inherit_stderr {
|
||||||
builder.inherit_stderr();
|
builder = builder.inherit_stderr();
|
||||||
} else if let Some(file) = config.stderr {
|
} else if let Some(file) = config.stderr {
|
||||||
builder.stderr(OsFile::try_from(file)?);
|
let file = unsafe { cap_std::fs::File::from_std(file) };
|
||||||
|
let file = wasi_cap_std_sync::file::File::from_cap_std(file);
|
||||||
|
builder = builder.stderr(Box::new(file));
|
||||||
}
|
}
|
||||||
for preopen in config.preopens {
|
for (dir, path) in config.preopens {
|
||||||
builder.preopened_dir(preopen.0, preopen.1);
|
builder = builder.preopened_dir(dir, path)?;
|
||||||
}
|
}
|
||||||
Ok(builder.build()?)
|
Ok(Rc::new(RefCell::new(builder.build()?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ impl WasiCtxBuilder {
|
|||||||
}
|
}
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
pub fn inherit_args(self) -> Result<Self, wasi_common::StringArrayError> {
|
||||||
|
let mut s = self.0;
|
||||||
|
for arg in std::env::args() {
|
||||||
|
s = s.arg(&arg)?;
|
||||||
|
}
|
||||||
|
Ok(WasiCtxBuilder(s))
|
||||||
|
}
|
||||||
pub fn stdin(self, f: Box<dyn WasiFile>) -> Self {
|
pub fn stdin(self, f: Box<dyn WasiFile>) -> Self {
|
||||||
WasiCtxBuilder(self.0.stdin(f))
|
WasiCtxBuilder(self.0.stdin(f))
|
||||||
}
|
}
|
||||||
@@ -59,10 +66,17 @@ impl WasiCtxBuilder {
|
|||||||
pub fn stderr(self, f: Box<dyn WasiFile>) -> Self {
|
pub fn stderr(self, f: Box<dyn WasiFile>) -> Self {
|
||||||
WasiCtxBuilder(self.0.stderr(f))
|
WasiCtxBuilder(self.0.stderr(f))
|
||||||
}
|
}
|
||||||
pub fn inherit_stdio(self) -> Self {
|
pub fn inherit_stdin(self) -> Self {
|
||||||
self.stdin(Box::new(crate::stdio::stdin()))
|
self.stdin(Box::new(crate::stdio::stdin()))
|
||||||
.stdout(Box::new(crate::stdio::stdout()))
|
}
|
||||||
.stderr(Box::new(crate::stdio::stderr()))
|
pub fn inherit_stdout(self) -> Self {
|
||||||
|
self.stdout(Box::new(crate::stdio::stdout()))
|
||||||
|
}
|
||||||
|
pub fn inherit_stderr(self) -> Self {
|
||||||
|
self.stderr(Box::new(crate::stdio::stderr()))
|
||||||
|
}
|
||||||
|
pub fn inherit_stdio(self) -> Self {
|
||||||
|
self.inherit_stdin().inherit_stdout().inherit_stderr()
|
||||||
}
|
}
|
||||||
pub fn preopened_dir(
|
pub fn preopened_dir(
|
||||||
self,
|
self,
|
||||||
|
|||||||
Reference in New Issue
Block a user