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
use crate::{FuncType, GlobalType, MemoryType, ModuleError, Mutability, TableType};
use wasmi_core::ValueType;
impl TryFrom<wasmparser::TableType> for TableType {
type Error = ModuleError;
fn try_from(table_type: wasmparser::TableType) -> Result<Self, Self::Error> {
if table_type.element_type != wasmparser::ValType::FuncRef {
return Err(ModuleError::unsupported(table_type));
}
let initial = table_type.initial as usize;
let maximum = table_type.maximum.map(|value| value as usize);
Ok(TableType::new(initial, maximum))
}
}
impl TryFrom<wasmparser::MemoryType> for MemoryType {
type Error = ModuleError;
fn try_from(memory_type: wasmparser::MemoryType) -> Result<Self, Self::Error> {
let make_error = || ModuleError::unsupported(memory_type);
let into_error = |_error| make_error();
if memory_type.memory64 || memory_type.shared {
return Err(make_error());
}
let initial = memory_type.initial.try_into().map_err(into_error)?;
let maximum = memory_type
.maximum
.map(|value| value.try_into())
.transpose()
.map_err(into_error)?;
Ok(MemoryType::new(initial, maximum))
}
}
impl TryFrom<wasmparser::GlobalType> for GlobalType {
type Error = ModuleError;
fn try_from(global_type: wasmparser::GlobalType) -> Result<Self, Self::Error> {
let value_type = value_type_try_from_wasmparser(global_type.content_type)?;
let mutability = match global_type.mutable {
true => Mutability::Mutable,
false => Mutability::Const,
};
Ok(GlobalType::new(value_type, mutability))
}
}
impl TryFrom<wasmparser::FuncType> for FuncType {
type Error = ModuleError;
fn try_from(func_type: wasmparser::FuncType) -> Result<Self, Self::Error> {
fn is_supported_value_type(value_type: &wasmparser::ValType) -> bool {
value_type_try_from_wasmparser(*value_type).is_ok()
}
if !func_type.params().iter().all(is_supported_value_type)
|| !func_type.results().iter().all(is_supported_value_type)
{
return Err(ModuleError::unsupported(func_type));
}
fn extract_value_type(value_type: &wasmparser::ValType) -> ValueType {
value_type_from_wasmparser(*value_type)
.expect("encountered unexpected invalid value type")
}
let params = func_type.params().iter().map(extract_value_type);
let results = func_type.results().iter().map(extract_value_type);
let func_type = FuncType::new(params, results);
Ok(func_type)
}
}
pub fn value_type_from_wasmparser(value_type: wasmparser::ValType) -> Option<ValueType> {
match value_type {
wasmparser::ValType::I32 => Some(ValueType::I32),
wasmparser::ValType::I64 => Some(ValueType::I64),
wasmparser::ValType::F32 => Some(ValueType::F32),
wasmparser::ValType::F64 => Some(ValueType::F64),
wasmparser::ValType::V128
| wasmparser::ValType::FuncRef
| wasmparser::ValType::ExternRef => None,
}
}
pub fn value_type_try_from_wasmparser(
value_type: wasmparser::ValType,
) -> Result<ValueType, ModuleError> {
value_type_from_wasmparser(value_type).ok_or_else(|| ModuleError::unsupported(value_type))
}