-
Notifications
You must be signed in to change notification settings - Fork 256
/
module.rs
121 lines (111 loc) · 3.73 KB
/
module.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::Result;
use wasm_encoder::{BlockType, HeapType, RefType, ValType};
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum PrimitiveTypeInfo {
I32,
I64,
F32,
F64,
V128,
FuncRef,
ExternRef,
Empty,
}
#[derive(Debug, Clone)]
pub struct FuncInfo {
pub params: Vec<PrimitiveTypeInfo>,
pub returns: Vec<PrimitiveTypeInfo>,
}
#[derive(Debug, Clone)]
pub enum TypeInfo {
Func(FuncInfo),
// TODO: module linking support will require instance and module types.
}
impl From<wasmparser::ValType> for PrimitiveTypeInfo {
fn from(value: wasmparser::ValType) -> Self {
match value {
wasmparser::ValType::I32 => PrimitiveTypeInfo::I32,
wasmparser::ValType::I64 => PrimitiveTypeInfo::I64,
wasmparser::ValType::F32 => PrimitiveTypeInfo::F32,
wasmparser::ValType::F64 => PrimitiveTypeInfo::F64,
wasmparser::ValType::V128 => PrimitiveTypeInfo::V128,
wasmparser::ValType::Ref(t) => t.into(),
}
}
}
impl From<wasmparser::RefType> for PrimitiveTypeInfo {
fn from(value: wasmparser::RefType) -> Self {
match value {
wasmparser::RefType::FUNCREF => PrimitiveTypeInfo::FuncRef,
wasmparser::RefType::EXTERNREF => PrimitiveTypeInfo::ExternRef,
_ => unimplemented!(),
}
}
}
impl From<wasmparser::FuncType> for TypeInfo {
fn from(ft: wasmparser::FuncType) -> Self {
TypeInfo::Func(FuncInfo {
params: ft
.params()
.iter()
.map(|&t| PrimitiveTypeInfo::from(t))
.collect(),
returns: ft
.results()
.iter()
.map(|&t| PrimitiveTypeInfo::from(t))
.collect(),
})
}
}
pub fn map_type(tpe: wasmparser::ValType) -> Result<ValType> {
match tpe {
wasmparser::ValType::I32 => Ok(ValType::I32),
wasmparser::ValType::I64 => Ok(ValType::I64),
wasmparser::ValType::F32 => Ok(ValType::F32),
wasmparser::ValType::F64 => Ok(ValType::F64),
wasmparser::ValType::V128 => Ok(ValType::V128),
wasmparser::ValType::Ref(t) => Ok(ValType::Ref(map_ref_type(t)?)),
}
}
pub fn map_ref_type(ref_ty: wasmparser::RefType) -> Result<RefType> {
Ok(RefType {
nullable: ref_ty.is_nullable(),
heap_type: match ref_ty.heap_type() {
wasmparser::HeapType::Concrete(i) => HeapType::Concrete(i.as_module_index().unwrap()),
wasmparser::HeapType::Abstract { shared, ty } => {
let ty = ty.into();
HeapType::Abstract { shared, ty }
}
},
})
}
pub fn map_block_type(ty: wasmparser::BlockType) -> Result<BlockType> {
match ty {
wasmparser::BlockType::Empty => Ok(BlockType::Empty),
wasmparser::BlockType::Type(ty) => Ok(BlockType::Result(map_type(ty)?)),
wasmparser::BlockType::FuncType(f) => Ok(BlockType::FunctionType(f)),
}
}
// The SectionId is stored as a `u8`. This macro will ensure that all of the `SectionId`s are
// matched and also takes care of converting the patterns to `u8` for matching.
macro_rules! match_section_id {
(match $scrutinee:expr;
$($pat:ident => $result:expr,)*
_ => $otherwise:expr,
) => {'result: loop {
#[allow(unreachable_code, non_upper_case_globals)]
{
$(const $pat: u8 = SectionId::$pat as u8;)*
break 'result match $scrutinee {
$($pat => $result,)*
_ => $otherwise,
};
// Check exhaustiveness of the SectionId match
match SectionId::Type {
$(SectionId::$pat => (),)*
};
}
}}
}
pub(crate) use match_section_id;