Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 36 additions & 26 deletions crates/wac-types/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,17 @@ impl fmt::Display for CoreExtern {
}
}

impl From<wasmparser::TableType> for CoreExtern {
fn from(ty: wasmparser::TableType) -> Self {
Self::Table {
element_type: ty.element_type.into(),
impl TryFrom<wasmparser::TableType> for CoreExtern {
type Error = anyhow::Error;

fn try_from(ty: wasmparser::TableType) -> anyhow::Result<Self> {
Ok(Self::Table {
element_type: ty.element_type.try_into()?,
initial: ty.initial,
maximum: ty.maximum,
table64: ty.table64,
shared: ty.shared,
}
})
}
}

Expand All @@ -135,13 +137,15 @@ impl From<wasmparser::MemoryType> for CoreExtern {
}
}

impl From<wasmparser::GlobalType> for CoreExtern {
fn from(ty: wasmparser::GlobalType) -> Self {
Self::Global {
val_type: ty.content_type.into(),
impl TryFrom<wasmparser::GlobalType> for CoreExtern {
type Error = anyhow::Error;

fn try_from(ty: wasmparser::GlobalType) -> anyhow::Result<Self> {
Ok(Self::Global {
val_type: ty.content_type.try_into()?,
mutable: ty.mutable,
shared: ty.shared,
}
})
}
}

Expand Down Expand Up @@ -177,16 +181,18 @@ impl fmt::Display for CoreType {
}
}

impl From<wasmparser::ValType> for CoreType {
fn from(ty: wasmparser::ValType) -> Self {
match ty {
impl TryFrom<wasmparser::ValType> for CoreType {
type Error = anyhow::Error;

fn try_from(ty: wasmparser::ValType) -> anyhow::Result<Self> {
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()?),
})
}
}

Expand Down Expand Up @@ -253,12 +259,14 @@ impl fmt::Display for CoreRefType {
}
}

impl From<wasmparser::RefType> for CoreRefType {
fn from(ty: wasmparser::RefType) -> Self {
Self {
impl TryFrom<wasmparser::RefType> for CoreRefType {
type Error = anyhow::Error;

fn try_from(ty: wasmparser::RefType) -> anyhow::Result<Self> {
Ok(Self {
nullable: ty.is_nullable(),
heap_type: ty.heap_type().into(),
}
heap_type: ty.heap_type().try_into()?,
})
}
}

Expand Down Expand Up @@ -316,9 +324,11 @@ pub enum HeapType {
NoCont,
}

impl From<wasmparser::HeapType> for HeapType {
fn from(ty: wasmparser::HeapType) -> Self {
match ty {
impl TryFrom<wasmparser::HeapType> for HeapType {
type Error = anyhow::Error;

fn try_from(ty: wasmparser::HeapType) -> anyhow::Result<Self> {
Ok(match ty {
wasmparser::HeapType::Abstract { shared: false, ty } => match ty {
wasmparser::AbstractHeapType::Any => Self::Any,
wasmparser::AbstractHeapType::Func => Self::Func,
Expand All @@ -336,15 +346,15 @@ impl From<wasmparser::HeapType> 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")
}
}
})
}
}

Expand Down
44 changes: 28 additions & 16 deletions crates/wac-types/src/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,14 +462,16 @@ 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::<Result<_>>()?;

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::<Result<_>>()?;

let module_id = self.types.add_module_type(ModuleType { imports, exports });
self.cache
Expand Down Expand Up @@ -803,25 +805,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<CoreExtern> {
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<CoreFuncType> {
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::<Result<_>>()?,
results: func_ty
.results()
.iter()
.copied()
.map(TryInto::try_into)
.collect::<Result<_>>()?,
})
}

fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<&(Owner, String)> {
Expand Down
48 changes: 48 additions & 0 deletions crates/wac-types/tests/heap_type_conversion.rs
Original file line number Diff line number Diff line change
@@ -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<HeapType, _> = 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<HeapType, _> = 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<HeapType, _> = heap.try_into();
assert!(result.is_ok(), "non-shared heap types should convert fine");
assert_eq!(result.unwrap(), HeapType::Func);
}