use crate::{
core::ValType,
engine::DedupFuncType,
module::{utils::WasmiValueType, FuncTypeIdx, ModuleHeader},
Engine,
};
#[derive(Debug, Copy, Clone)]
pub struct BlockType {
inner: BlockTypeInner,
}
#[derive(Debug, Copy, Clone)]
pub enum BlockTypeInner {
Empty,
Returns,
FuncType(DedupFuncType),
}
impl BlockType {
pub fn new(block_type: wasmparser::BlockType, res: &ModuleHeader) -> Self {
match block_type {
wasmparser::BlockType::Empty => Self::empty(),
wasmparser::BlockType::Type(return_type) => {
let return_type = WasmiValueType::from(return_type).into_inner();
Self::returns(return_type)
}
wasmparser::BlockType::FuncType(func_type_idx) => {
let dedup_func_type = res.get_func_type(FuncTypeIdx::from(func_type_idx));
Self::func_type(dedup_func_type)
}
}
}
fn from_inner(inner: BlockTypeInner) -> Self {
Self { inner }
}
fn empty() -> Self {
Self::from_inner(BlockTypeInner::Empty)
}
fn returns(_return_type: ValType) -> Self {
Self::from_inner(BlockTypeInner::Returns)
}
pub(crate) fn func_type(func_type: &DedupFuncType) -> Self {
Self::from_inner(BlockTypeInner::FuncType(*func_type))
}
pub fn len_params(&self, engine: &Engine) -> usize {
match &self.inner {
BlockTypeInner::Empty | BlockTypeInner::Returns => 0,
BlockTypeInner::FuncType(func_type) => {
engine.resolve_func_type(func_type, |func_type| func_type.params().len())
}
}
}
pub fn len_results(&self, engine: &Engine) -> usize {
match &self.inner {
BlockTypeInner::Empty => 0,
BlockTypeInner::Returns => 1,
BlockTypeInner::FuncType(func_type) => {
engine.resolve_func_type(func_type, |func_type| func_type.results().len())
}
}
}
}