Coverage Report

Created: 2026-07-05 07:39

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
445k
    fn try_from(value: wasmparser::ValType) -> Result<Self> {
32
445k
        Ok(match value {
33
32.4k
            wasmparser::ValType::I32 => PrimitiveTypeInfo::I32,
34
154k
            wasmparser::ValType::I64 => PrimitiveTypeInfo::I64,
35
17.4k
            wasmparser::ValType::F32 => PrimitiveTypeInfo::F32,
36
119k
            wasmparser::ValType::F64 => PrimitiveTypeInfo::F64,
37
8.53k
            wasmparser::ValType::V128 => PrimitiveTypeInfo::V128,
38
112k
            wasmparser::ValType::Ref(t) => t.try_into()?,
39
        })
40
445k
    }
41
}
42
43
impl TryFrom<wasmparser::RefType> for PrimitiveTypeInfo {
44
    type Error = Error;
45
46
112k
    fn try_from(value: wasmparser::RefType) -> Result<Self> {
47
112k
        Ok(match value {
48
106k
            wasmparser::RefType::FUNCREF => PrimitiveTypeInfo::FuncRef,
49
6.36k
            wasmparser::RefType::EXTERNREF => PrimitiveTypeInfo::ExternRef,
50
95
            other => return Err(Error::unsupported(format!("type {other:?}"))),
51
        })
52
112k
    }
53
}
54
55
impl TryFrom<wasmparser::FuncType> for TypeInfo {
56
    type Error = Error;
57
58
25.1k
    fn try_from(ft: wasmparser::FuncType) -> Result<Self> {
59
        Ok(TypeInfo::Func(FuncInfo {
60
25.1k
            params: ft
61
25.1k
                .params()
62
25.1k
                .iter()
63
353k
                .map(|&t| PrimitiveTypeInfo::try_from(t))
64
25.1k
                .collect::<Result<_>>()?,
65
25.1k
            returns: ft
66
25.1k
                .results()
67
25.1k
                .iter()
68
47.6k
                .map(|&t| PrimitiveTypeInfo::try_from(t))
69
25.1k
                .collect::<Result<_>>()?,
70
        }))
71
25.1k
    }
72
}
73
74
45.5k
pub fn map_type(tpe: wasmparser::ValType) -> Result<ValType> {
75
45.5k
    match tpe {
76
13.8k
        wasmparser::ValType::I32 => Ok(ValType::I32),
77
11.7k
        wasmparser::ValType::I64 => Ok(ValType::I64),
78
5.30k
        wasmparser::ValType::F32 => Ok(ValType::F32),
79
9.63k
        wasmparser::ValType::F64 => Ok(ValType::F64),
80
3.97k
        wasmparser::ValType::V128 => Ok(ValType::V128),
81
1.02k
        wasmparser::ValType::Ref(t) => Ok(ValType::Ref(map_ref_type(t)?)),
82
    }
83
45.5k
}
84
85
1.02k
pub fn map_ref_type(ref_ty: wasmparser::RefType) -> Result<RefType> {
86
    Ok(RefType {
87
1.02k
        nullable: ref_ty.is_nullable(),
88
1.02k
        heap_type: match ref_ty.heap_type() {
89
18
            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
1.00k
            wasmparser::HeapType::Abstract { shared, ty } => {
92
1.00k
                let ty = ty.into();
93
1.00k
                HeapType::Abstract { shared, ty }
94
            }
95
        },
96
    })
97
1.02k
}
98
99
2.42k
pub fn map_block_type(ty: wasmparser::BlockType) -> Result<BlockType> {
100
2.42k
    match ty {
101
1.88k
        wasmparser::BlockType::Empty => Ok(BlockType::Empty),
102
431
        wasmparser::BlockType::Type(ty) => Ok(BlockType::Result(map_type(ty)?)),
103
102
        wasmparser::BlockType::FuncType(f) => Ok(BlockType::FunctionType(f)),
104
    }
105
2.42k
}
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;