Skip to content

Commit 6fd4d45

Browse files
committed
Replace panics with errors for unsupported heap type conversions
The From<wasmparser::HeapType> 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.
1 parent e1e684a commit 6fd4d45

File tree

3 files changed

+110
-42
lines changed

3 files changed

+110
-42
lines changed

crates/wac-types/src/core.rs

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,17 @@ impl fmt::Display for CoreExtern {
111111
}
112112
}
113113

114-
impl From<wasmparser::TableType> for CoreExtern {
115-
fn from(ty: wasmparser::TableType) -> Self {
116-
Self::Table {
117-
element_type: ty.element_type.into(),
114+
impl TryFrom<wasmparser::TableType> for CoreExtern {
115+
type Error = anyhow::Error;
116+
117+
fn try_from(ty: wasmparser::TableType) -> anyhow::Result<Self> {
118+
Ok(Self::Table {
119+
element_type: ty.element_type.try_into()?,
118120
initial: ty.initial,
119121
maximum: ty.maximum,
120122
table64: ty.table64,
121123
shared: ty.shared,
122-
}
124+
})
123125
}
124126
}
125127

@@ -135,13 +137,15 @@ impl From<wasmparser::MemoryType> for CoreExtern {
135137
}
136138
}
137139

138-
impl From<wasmparser::GlobalType> for CoreExtern {
139-
fn from(ty: wasmparser::GlobalType) -> Self {
140-
Self::Global {
141-
val_type: ty.content_type.into(),
140+
impl TryFrom<wasmparser::GlobalType> for CoreExtern {
141+
type Error = anyhow::Error;
142+
143+
fn try_from(ty: wasmparser::GlobalType) -> anyhow::Result<Self> {
144+
Ok(Self::Global {
145+
val_type: ty.content_type.try_into()?,
142146
mutable: ty.mutable,
143147
shared: ty.shared,
144-
}
148+
})
145149
}
146150
}
147151

@@ -177,16 +181,18 @@ impl fmt::Display for CoreType {
177181
}
178182
}
179183

180-
impl From<wasmparser::ValType> for CoreType {
181-
fn from(ty: wasmparser::ValType) -> Self {
182-
match ty {
184+
impl TryFrom<wasmparser::ValType> for CoreType {
185+
type Error = anyhow::Error;
186+
187+
fn try_from(ty: wasmparser::ValType) -> anyhow::Result<Self> {
188+
Ok(match ty {
183189
wasmparser::ValType::I32 => Self::I32,
184190
wasmparser::ValType::I64 => Self::I64,
185191
wasmparser::ValType::F32 => Self::F32,
186192
wasmparser::ValType::F64 => Self::F64,
187193
wasmparser::ValType::V128 => Self::V128,
188-
wasmparser::ValType::Ref(ty) => Self::Ref(ty.into()),
189-
}
194+
wasmparser::ValType::Ref(ty) => Self::Ref(ty.try_into()?),
195+
})
190196
}
191197
}
192198

@@ -253,12 +259,14 @@ impl fmt::Display for CoreRefType {
253259
}
254260
}
255261

256-
impl From<wasmparser::RefType> for CoreRefType {
257-
fn from(ty: wasmparser::RefType) -> Self {
258-
Self {
262+
impl TryFrom<wasmparser::RefType> for CoreRefType {
263+
type Error = anyhow::Error;
264+
265+
fn try_from(ty: wasmparser::RefType) -> anyhow::Result<Self> {
266+
Ok(Self {
259267
nullable: ty.is_nullable(),
260-
heap_type: ty.heap_type().into(),
261-
}
268+
heap_type: ty.heap_type().try_into()?,
269+
})
262270
}
263271
}
264272

@@ -316,9 +324,11 @@ pub enum HeapType {
316324
NoCont,
317325
}
318326

319-
impl From<wasmparser::HeapType> for HeapType {
320-
fn from(ty: wasmparser::HeapType) -> Self {
321-
match ty {
327+
impl TryFrom<wasmparser::HeapType> for HeapType {
328+
type Error = anyhow::Error;
329+
330+
fn try_from(ty: wasmparser::HeapType) -> anyhow::Result<Self> {
331+
Ok(match ty {
322332
wasmparser::HeapType::Abstract { shared: false, ty } => match ty {
323333
wasmparser::AbstractHeapType::Any => Self::Any,
324334
wasmparser::AbstractHeapType::Func => Self::Func,
@@ -336,15 +346,15 @@ impl From<wasmparser::HeapType> for HeapType {
336346
wasmparser::AbstractHeapType::NoCont => Self::NoCont,
337347
},
338348
wasmparser::HeapType::Abstract { shared: true, ty } => {
339-
panic!("shared heap types are not supported: {:?}", ty)
349+
anyhow::bail!("shared heap types are not supported: {ty:?}")
340350
}
341351
wasmparser::HeapType::Concrete(index) => {
342352
Self::Concrete(index.as_module_index().unwrap())
343353
}
344354
wasmparser::HeapType::Exact(_) => {
345-
todo!("wasmparser::HeapType::Exact");
355+
anyhow::bail!("exact heap types are not yet supported")
346356
}
347-
}
357+
})
348358
}
349359
}
350360

crates/wac-types/src/package.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -462,14 +462,14 @@ impl<'a> TypeConverter<'a> {
462462
let imports = module_ty
463463
.imports
464464
.iter()
465-
.map(|((module, name), ty)| ((module.clone(), name.clone()), self.entity_type(*ty)))
466-
.collect();
465+
.map(|((module, name), ty)| Ok(((module.clone(), name.clone()), self.entity_type(*ty)?)))
466+
.collect::<Result<_>>()?;
467467

468468
let exports = module_ty
469469
.exports
470470
.iter()
471-
.map(|(name, ty)| (name.clone(), self.entity_type(*ty)))
472-
.collect();
471+
.map(|(name, ty)| Ok((name.clone(), self.entity_type(*ty)?)))
472+
.collect::<Result<_>>()?;
473473

474474
let module_id = self.types.add_module_type(ModuleType { imports, exports });
475475
self.cache
@@ -803,25 +803,35 @@ impl<'a> TypeConverter<'a> {
803803
resource_id
804804
}
805805

806-
fn entity_type(&self, ty: wasmparser::types::EntityType) -> CoreExtern {
807-
match ty {
808-
wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)),
809-
wasmparser::types::EntityType::Table(ty) => ty.into(),
806+
fn entity_type(&self, ty: wasmparser::types::EntityType) -> Result<CoreExtern> {
807+
Ok(match ty {
808+
wasmparser::types::EntityType::Func(ty) => CoreExtern::Func(self.func_type(ty)?),
809+
wasmparser::types::EntityType::Table(ty) => ty.try_into()?,
810810
wasmparser::types::EntityType::Memory(ty) => ty.into(),
811-
wasmparser::types::EntityType::Global(ty) => ty.into(),
812-
wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)),
811+
wasmparser::types::EntityType::Global(ty) => ty.try_into()?,
812+
wasmparser::types::EntityType::Tag(ty) => CoreExtern::Tag(self.func_type(ty)?),
813813
wasmparser::types::EntityType::FuncExact(_) => {
814814
todo!("wasmparser::types::EntityType::FuncExact")
815815
}
816-
}
816+
})
817817
}
818818

819-
fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> CoreFuncType {
819+
fn func_type(&self, ty: wasmparser::types::CoreTypeId) -> Result<CoreFuncType> {
820820
let func_ty = self.wasm_types[ty].unwrap_func();
821-
CoreFuncType {
822-
params: func_ty.params().iter().copied().map(Into::into).collect(),
823-
results: func_ty.results().iter().copied().map(Into::into).collect(),
824-
}
821+
Ok(CoreFuncType {
822+
params: func_ty
823+
.params()
824+
.iter()
825+
.copied()
826+
.map(TryInto::try_into)
827+
.collect::<Result<_>>()?,
828+
results: func_ty
829+
.results()
830+
.iter()
831+
.copied()
832+
.map(TryInto::try_into)
833+
.collect::<Result<_>>()?,
834+
})
825835
}
826836

827837
fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<&(Owner, String)> {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use wac_types::HeapType;
2+
3+
#[test]
4+
fn shared_heap_type_returns_error() {
5+
let shared_heap = wasmparser::HeapType::Abstract {
6+
shared: true,
7+
ty: wasmparser::AbstractHeapType::Func,
8+
};
9+
10+
let result: Result<HeapType, _> = shared_heap.try_into();
11+
assert!(
12+
result.is_err(),
13+
"shared heap types should return an error, not panic"
14+
);
15+
let err = result.unwrap_err().to_string();
16+
assert!(
17+
err.contains("shared heap types are not supported"),
18+
"error should mention shared heap types: {err}"
19+
);
20+
}
21+
22+
#[test]
23+
fn exact_heap_type_returns_error() {
24+
let exact_heap = wasmparser::HeapType::Exact(wasmparser::UnpackedIndex::Module(0));
25+
26+
let result: Result<HeapType, _> = exact_heap.try_into();
27+
assert!(
28+
result.is_err(),
29+
"exact heap types should return an error, not panic"
30+
);
31+
let err = result.unwrap_err().to_string();
32+
assert!(
33+
err.contains("not yet supported"),
34+
"error should mention unsupported: {err}"
35+
);
36+
}
37+
38+
#[test]
39+
fn non_shared_heap_type_succeeds() {
40+
let heap = wasmparser::HeapType::Abstract {
41+
shared: false,
42+
ty: wasmparser::AbstractHeapType::Func,
43+
};
44+
45+
let result: Result<HeapType, _> = heap.try_into();
46+
assert!(result.is_ok(), "non-shared heap types should convert fine");
47+
assert_eq!(result.unwrap(), HeapType::Func);
48+
}

0 commit comments

Comments
 (0)