From 6fd4d45d46720725c6d3744b637b61d4d30a5292 Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Thu, 12 Feb 2026 20:11:33 +0800 Subject: [PATCH 1/2] Replace panics with errors for unsupported heap type conversions The From impl panicked on shared heap types and used todo!() for exact heap types. Converted the entire chain of From impls to TryFrom (HeapType, RefType, CoreType, and the Table/Global CoreExtern conversions) so that unsupported types produce proper errors instead of crashing at runtime. Updated all call sites in package.rs to propagate errors via try_into. Added tests verifying that shared and exact heap types return errors. --- crates/wac-types/src/core.rs | 62 +++++++++++-------- crates/wac-types/src/package.rs | 42 ++++++++----- .../wac-types/tests/heap_type_conversion.rs | 48 ++++++++++++++ 3 files changed, 110 insertions(+), 42 deletions(-) create mode 100644 crates/wac-types/tests/heap_type_conversion.rs diff --git a/crates/wac-types/src/core.rs b/crates/wac-types/src/core.rs index 87de30d..67fdbeb 100644 --- a/crates/wac-types/src/core.rs +++ b/crates/wac-types/src/core.rs @@ -111,15 +111,17 @@ impl fmt::Display for CoreExtern { } } -impl From for CoreExtern { - fn from(ty: wasmparser::TableType) -> Self { - Self::Table { - element_type: ty.element_type.into(), +impl TryFrom for CoreExtern { + type Error = anyhow::Error; + + fn try_from(ty: wasmparser::TableType) -> anyhow::Result { + Ok(Self::Table { + element_type: ty.element_type.try_into()?, initial: ty.initial, maximum: ty.maximum, table64: ty.table64, shared: ty.shared, - } + }) } } @@ -135,13 +137,15 @@ impl From for CoreExtern { } } -impl From for CoreExtern { - fn from(ty: wasmparser::GlobalType) -> Self { - Self::Global { - val_type: ty.content_type.into(), +impl TryFrom for CoreExtern { + type Error = anyhow::Error; + + fn try_from(ty: wasmparser::GlobalType) -> anyhow::Result { + Ok(Self::Global { + val_type: ty.content_type.try_into()?, mutable: ty.mutable, shared: ty.shared, - } + }) } } @@ -177,16 +181,18 @@ impl fmt::Display for CoreType { } } -impl From for CoreType { - fn from(ty: wasmparser::ValType) -> Self { - match ty { +impl TryFrom for CoreType { + type Error = anyhow::Error; + + fn try_from(ty: wasmparser::ValType) -> anyhow::Result { + Ok(match ty { wasmparser::ValType::I32 => Self::I32, wasmparser::ValType::I64 => Self::I64, wasmparser::ValType::F32 => Self::F32, wasmparser::ValType::F64 => Self::F64, wasmparser::ValType::V128 => Self::V128, - wasmparser::ValType::Ref(ty) => Self::Ref(ty.into()), - } + wasmparser::ValType::Ref(ty) => Self::Ref(ty.try_into()?), + }) } } @@ -253,12 +259,14 @@ impl fmt::Display for CoreRefType { } } -impl From for CoreRefType { - fn from(ty: wasmparser::RefType) -> Self { - Self { +impl TryFrom for CoreRefType { + type Error = anyhow::Error; + + fn try_from(ty: wasmparser::RefType) -> anyhow::Result { + Ok(Self { nullable: ty.is_nullable(), - heap_type: ty.heap_type().into(), - } + heap_type: ty.heap_type().try_into()?, + }) } } @@ -316,9 +324,11 @@ pub enum HeapType { NoCont, } -impl From for HeapType { - fn from(ty: wasmparser::HeapType) -> Self { - match ty { +impl TryFrom for HeapType { + type Error = anyhow::Error; + + fn try_from(ty: wasmparser::HeapType) -> anyhow::Result { + Ok(match ty { wasmparser::HeapType::Abstract { shared: false, ty } => match ty { wasmparser::AbstractHeapType::Any => Self::Any, wasmparser::AbstractHeapType::Func => Self::Func, @@ -336,15 +346,15 @@ impl From for HeapType { wasmparser::AbstractHeapType::NoCont => Self::NoCont, }, wasmparser::HeapType::Abstract { shared: true, ty } => { - panic!("shared heap types are not supported: {:?}", ty) + anyhow::bail!("shared heap types are not supported: {ty:?}") } wasmparser::HeapType::Concrete(index) => { Self::Concrete(index.as_module_index().unwrap()) } wasmparser::HeapType::Exact(_) => { - todo!("wasmparser::HeapType::Exact"); + anyhow::bail!("exact heap types are not yet supported") } - } + }) } } diff --git a/crates/wac-types/src/package.rs b/crates/wac-types/src/package.rs index af6a923..cf26db3 100644 --- a/crates/wac-types/src/package.rs +++ b/crates/wac-types/src/package.rs @@ -462,14 +462,14 @@ impl<'a> TypeConverter<'a> { let imports = module_ty .imports .iter() - .map(|((module, name), ty)| ((module.clone(), name.clone()), self.entity_type(*ty))) - .collect(); + .map(|((module, name), ty)| Ok(((module.clone(), name.clone()), self.entity_type(*ty)?))) + .collect::>()?; let exports = module_ty .exports .iter() - .map(|(name, ty)| (name.clone(), self.entity_type(*ty))) - .collect(); + .map(|(name, ty)| Ok((name.clone(), self.entity_type(*ty)?))) + .collect::>()?; let module_id = self.types.add_module_type(ModuleType { imports, exports }); self.cache @@ -803,25 +803,35 @@ impl<'a> TypeConverter<'a> { resource_id } - fn entity_type(&self, ty: wasmparser::types::EntityType) -> CoreExtern { - match ty { - wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)), - wasmparser::types::EntityType::Table(ty) => ty.into(), + fn entity_type(&self, ty: wasmparser::types::EntityType) -> Result { + Ok(match ty { + wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)?), + wasmparser::types::EntityType::Table(ty) => ty.try_into()?, wasmparser::types::EntityType::Memory(ty) => ty.into(), - wasmparser::types::EntityType::Global(ty) => ty.into(), - wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)), + wasmparser::types::EntityType::Global(ty) => ty.try_into()?, + wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)?), wasmparser::types::EntityType::FuncExact(_) => { todo!("wasmparser::types::EntityType::FuncExact") } - } + }) } - fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> CoreFuncType { + fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> Result { let func_ty = self.wasm_types[ty].unwrap_func(); - CoreFuncType { - params: func_ty.params().iter().copied().map(Into::into).collect(), - results: func_ty.results().iter().copied().map(Into::into).collect(), - } + Ok(CoreFuncType { + params: func_ty + .params() + .iter() + .copied() + .map(TryInto::try_into) + .collect::>()?, + results: func_ty + .results() + .iter() + .copied() + .map(TryInto::try_into) + .collect::>()?, + }) } fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<&(Owner, String)> { diff --git a/crates/wac-types/tests/heap_type_conversion.rs b/crates/wac-types/tests/heap_type_conversion.rs new file mode 100644 index 0000000..0414f90 --- /dev/null +++ b/crates/wac-types/tests/heap_type_conversion.rs @@ -0,0 +1,48 @@ +use wac_types::HeapType; + +#[test] +fn shared_heap_type_returns_error() { + let shared_heap = wasmparser::HeapType::Abstract { + shared: true, + ty: wasmparser::AbstractHeapType::Func, + }; + + let result: Result = shared_heap.try_into(); + assert!( + result.is_err(), + "shared heap types should return an error, not panic" + ); + let err = result.unwrap_err().to_string(); + assert!( + err.contains("shared heap types are not supported"), + "error should mention shared heap types: {err}" + ); +} + +#[test] +fn exact_heap_type_returns_error() { + let exact_heap = wasmparser::HeapType::Exact(wasmparser::UnpackedIndex::Module(0)); + + let result: Result = exact_heap.try_into(); + assert!( + result.is_err(), + "exact heap types should return an error, not panic" + ); + let err = result.unwrap_err().to_string(); + assert!( + err.contains("not yet supported"), + "error should mention unsupported: {err}" + ); +} + +#[test] +fn non_shared_heap_type_succeeds() { + let heap = wasmparser::HeapType::Abstract { + shared: false, + ty: wasmparser::AbstractHeapType::Func, + }; + + let result: Result = heap.try_into(); + assert!(result.is_ok(), "non-shared heap types should convert fine"); + assert_eq!(result.unwrap(), HeapType::Func); +} From 2676523830e3904be358d66af71107d5bb8b0bd4 Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Thu, 12 Feb 2026 21:30:44 +0800 Subject: [PATCH 2/2] Run cargo fmt --- crates/wac-types/src/package.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/wac-types/src/package.rs b/crates/wac-types/src/package.rs index cf26db3..0ba9f76 100644 --- a/crates/wac-types/src/package.rs +++ b/crates/wac-types/src/package.rs @@ -462,7 +462,9 @@ impl<'a> TypeConverter<'a> { let imports = module_ty .imports .iter() - .map(|((module, name), ty)| Ok(((module.clone(), name.clone()), self.entity_type(*ty)?))) + .map(|((module, name), ty)| { + Ok(((module.clone(), name.clone()), self.entity_type(*ty)?)) + }) .collect::>()?; let exports = module_ty