Coverage Report

Created: 2026-10-12 08:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wasm-mutate/src/module.rs
Line
Count
Source
1
use crate::{Error, Result};
2
use wasm_encoder::{BlockType, HeapType, RefType, ValType};
3
4
#[derive(Debug, Copy, Clone, PartialEq)]
5
pub enum PrimitiveTypeInfo {
6
    I32,
7
    I64,
8
    F32,
9
    F64,
10
    V128,
11
    FuncRef,
12
    ExternRef,
13
    Empty,
14
}
15
16
#[derive(Debug, Clone)]
17
pub struct FuncInfo {
18
    pub params: Vec<PrimitiveTypeInfo>,
19
    pub returns: Vec<PrimitiveTypeInfo>,
20
}
21
22
#[derive(Debug, Clone)]
23
pub enum TypeInfo {
24
    Func(FuncInfo),
25
    // TODO: module linking support will require instance and module types.
26
}
27
28
impl TryFrom<wasmparser::ValType> for PrimitiveTypeInfo {
29
    type Error = Error;
30
31
413k
    fn try_from(value: wasmparser::ValType) -> Result<Self> {
32
413k
        Ok(match value {
33
30.0k
            wasmparser::ValType::I32 => PrimitiveTypeInfo::I32,
34
155k
            wasmparser::ValType::I64 => PrimitiveTypeInfo::I64,
35
27.1k
            wasmparser::ValType::F32 => PrimitiveTypeInfo::F32,
36
98.5k
            wasmparser::ValType::F64 => PrimitiveTypeInfo::F64,
37
22.8k
            wasmparser::ValType::V128 => PrimitiveTypeInfo::V128,
38
79.5k
            wasmparser::ValType::Ref(t) => t.try_into()?,
39
        })
40
413k
    }
41
}
42
43
impl TryFrom<wasmparser::RefType> for PrimitiveTypeInfo {
44
    type Error = Error;
45
46
79.5k
    fn try_from(value: wasmparser::RefType) -> Result<Self> {
47
79.5k
        Ok(match value {
48
68.7k
            wasmparser::RefType::FUNCREF => PrimitiveTypeInfo::FuncRef,
49
10.7k
            wasmparser::RefType::EXTERNREF => PrimitiveTypeInfo::ExternRef,
50
93
            other => return Err(Error::unsupported(format!("type {other:?}"))),
51
        })
52
79.5k
    }
53
}
54
55
impl TryFrom<wasmparser::FuncType> for TypeInfo {
56
    type Error = Error;
57
58
23.9k
    fn try_from(ft: wasmparser::FuncType) -> Result<Self> {
59
        Ok(TypeInfo::Func(FuncInfo {
60
23.9k
            params: ft
61
23.9k
                .params()
62
23.9k
                .iter()
63
305k
                .map(|&t| PrimitiveTypeInfo::try_from(t))
64
23.9k
                .collect::<Result<_>>()?,
65
23.9k
            returns: ft
66
23.9k
                .results()
67
23.9k
                .iter()
68
52.4k
                .map(|&t| PrimitiveTypeInfo::try_from(t))
69
23.9k
                .collect::<Result<_>>()?,
70
        }))
71
23.9k
    }
72
}
73
74
103k
pub fn map_type(tpe: wasmparser::ValType) -> Result<ValType> {
75
103k
    match tpe {
76
16.2k
        wasmparser::ValType::I32 => Ok(ValType::I32),
77
33.0k
        wasmparser::ValType::I64 => Ok(ValType::I64),
78
10.2k
        wasmparser::ValType::F32 => Ok(ValType::F32),
79
31.9k
        wasmparser::ValType::F64 => Ok(ValType::F64),
80
7.83k
        wasmparser::ValType::V128 => Ok(ValType::V128),
81
3.85k
        wasmparser::ValType::Ref(t) => Ok(ValType::Ref(map_ref_type(t)?)),
82
    }
83
103k
}
84
85
3.85k
pub fn map_ref_type(ref_ty: wasmparser::RefType) -> Result<RefType> {
86
    Ok(RefType {
87
3.85k
        nullable: ref_ty.is_nullable(),
88
3.85k
        heap_type: match ref_ty.heap_type() {
89
0
            wasmparser::HeapType::Concrete(i) => HeapType::Concrete(i.as_module_index().unwrap()),
90
0
            wasmparser::HeapType::Exact(i) => HeapType::Exact(i.as_module_index().unwrap()),
91
3.85k
            wasmparser::HeapType::Abstract { shared, ty } => {
92
3.85k
                let ty = ty.into();
93
3.85k
                HeapType::Abstract { shared, ty }
94
            }
95
        },
96
    })
97
3.85k
}
98
99
2.73k
pub fn map_block_type(ty: wasmparser::BlockType) -> Result<BlockType> {
100
2.73k
    match ty {
101
1.82k
        wasmparser::BlockType::Empty => Ok(BlockType::Empty),
102
842
        wasmparser::BlockType::Type(ty) => Ok(BlockType::Result(map_type(ty)?)),
103
62
        wasmparser::BlockType::FuncType(f) => Ok(BlockType::FunctionType(f)),
104
    }
105
2.73k
}
106
107
// The SectionId is stored as a `u8`. This macro will ensure that all of the `SectionId`s are
108
// matched and also takes care of converting the patterns to `u8` for matching.
109
macro_rules! match_section_id {
110
    (match $scrutinee:expr;
111
        $($pat:ident => $result:expr,)*
112
        _ => $otherwise:expr,
113
    ) => {'result: loop {
114
        #[allow(unreachable_code, non_upper_case_globals)]
115
        {
116
            $(const $pat: u8 = SectionId::$pat as u8;)*
117
            break 'result match $scrutinee {
118
                $($pat => $result,)*
119
                _ => $otherwise,
120
            };
121
            // Check exhaustiveness of the SectionId match
122
            match SectionId::Type {
123
                $(SectionId::$pat => (),)*
124
            };
125
        }
126
    }}
127
}
128
pub(crate) use match_section_id;