use anyhow::{anyhow, bail, Context, Result};
use wit_component::{decode, DecodedWasm};
use wit_parser::{InterfaceId, LiftLowerAbi, ManglingAndAbi, Resolve};
pub(crate) fn dispatch_mangling(is_async: bool) -> ManglingAndAbi {
ManglingAndAbi::Legacy(if is_async {
LiftLowerAbi::AsyncStackful
} else {
LiftLowerAbi::Sync
})
}
pub(crate) fn hook_callback_mangling() -> ManglingAndAbi {
ManglingAndAbi::Legacy(LiftLowerAbi::AsyncCallback)
}
pub(crate) fn sync_mangling() -> ManglingAndAbi {
ManglingAndAbi::Legacy(LiftLowerAbi::Sync)
}
pub(super) fn decode_input_resolve(split_bytes: &[u8]) -> Result<Resolve> {
let decoded = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| decode(split_bytes)))
.map_err(|_| {
anyhow!(
"wit-parser panic during component decode — likely the import + re-export \
of a resource-bearing instance (upstream issue \
https://github.com/bytecodealliance/wasm-tools/issues/2506). The new emit \
path can't proceed until that's fixed upstream."
)
})?
.context("wit_component::decode split")?;
match decoded {
DecodedWasm::Component(resolve, _world) => Ok(resolve),
DecodedWasm::WitPackage(_, _) => bail!(
"split bytes decoded to a WIT package; \
expected a component"
),
}
}
pub(super) fn find_target_interface(
resolve: &Resolve,
target_interface: &str,
) -> Result<InterfaceId> {
resolve
.interfaces
.iter()
.find(|(id, _)| resolve.id_of(*id).as_deref() == Some(target_interface))
.map(|(id, _)| id)
.ok_or_else(|| {
anyhow!(
"interface `{target_interface}` not found in \
the decoded WIT; available: {:?}",
resolve
.interfaces
.iter()
.filter_map(|(id, _)| resolve.id_of(id))
.collect::<Vec<_>>()
)
})
}