#![warn(missing_docs)]
use anyhow::Result;
use wasi_common::WasiCtx;
use wasmparser::{Parser, Payload};
use wasmtime::{Func, Linker, Store};
pub enum AutoWasi {
Snapshot0(wasmtime_wasi::old::snapshot_0::Wasi),
Snapshot1(wasmtime_wasi::Wasi),
}
impl AutoWasi {
pub fn detect<T: AsRef<[u8]>>(store: &Store, ctx: WasiCtx, binary: T) -> Result<Self> {
let version = WasiVersion::detect(binary)?;
Ok(Self::new(store, ctx, version))
}
pub fn new(store: &Store, ctx: WasiCtx, version: WasiVersion) -> Self {
match version {
WasiVersion::Snapshot0 => {
let wasi = wasmtime_wasi::old::snapshot_0::Wasi::new(&store, ctx);
Self::Snapshot0(wasi)
}
WasiVersion::Snapshot1 => {
let wasi = wasmtime_wasi::Wasi::new(&store, ctx);
Self::Snapshot1(wasi)
}
}
}
pub fn get_export(&self, name: &str) -> Option<&Func> {
match self {
Self::Snapshot0(wasi) => wasi.get_export(name),
Self::Snapshot1(wasi) => wasi.get_export(name),
}
}
pub fn add_to_linker(&self, linker: &mut Linker) -> Result<()> {
match self {
Self::Snapshot0(wasi) => wasi.add_to_linker(linker),
Self::Snapshot1(wasi) => wasi.add_to_linker(linker),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum WasiVersion {
Snapshot0,
Snapshot1,
}
impl WasiVersion {
pub fn detect<T: AsRef<[u8]>>(binary: T) -> Result<Self> {
for payload in Parser::new(0).parse_all(binary.as_ref()) {
match payload? {
Payload::ImportSection(reader) => {
for import in reader {
if import?.module == "wasi_unstable" {
return Ok(Self::Snapshot0);
}
}
}
_ => {}
}
}
Ok(Self::default())
}
}
impl Default for WasiVersion {
fn default() -> Self {
Self::Snapshot1
}
}