-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.rs
103 lines (91 loc) · 3.07 KB
/
types.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
use cranelift_codegen::ir;
use lucet_module::Signature;
use lucet_module::ValueType;
#[derive(Debug)]
pub enum ValueError {
Unrepresentable,
InvalidVMContext,
}
fn to_lucet_value(value: &ir::AbiParam) -> Result<ValueType, ValueError> {
match value {
ir::AbiParam {
value_type: cranelift_ty,
purpose: ir::ArgumentPurpose::Normal,
extension: ir::ArgumentExtension::None,
location: ir::ArgumentLoc::Unassigned,
} => {
let size = cranelift_ty.bits();
if cranelift_ty.is_int() {
match size {
32 => Ok(ValueType::I32),
64 => Ok(ValueType::I64),
_ => Err(ValueError::Unrepresentable),
}
} else if cranelift_ty.is_float() {
match size {
32 => Ok(ValueType::F32),
64 => Ok(ValueType::F64),
_ => Err(ValueError::Unrepresentable),
}
} else {
Err(ValueError::Unrepresentable)
}
}
_ => Err(ValueError::Unrepresentable),
}
}
#[derive(Debug)]
pub enum SignatureError {
BadElement(ir::AbiParam, ValueError),
BadSignature,
}
pub fn to_lucet_signature(value: &ir::Signature) -> Result<Signature, SignatureError> {
let mut params: Vec<ValueType> = Vec::new();
let mut param_iter = value.params.iter();
// Enforce that the first parameter is VMContext, as Signature assumes.
// Even functions declared no-arg take VMContext in reality.
if let Some(param) = param_iter.next() {
match ¶m {
ir::AbiParam {
value_type: value,
purpose: ir::ArgumentPurpose::VMContext,
extension: ir::ArgumentExtension::None,
location: ir::ArgumentLoc::Unassigned,
} => {
if value.is_int() && value.bits() == 64 {
// this is VMContext, so we can move on.
} else {
return Err(SignatureError::BadElement(
param.to_owned(),
ValueError::InvalidVMContext,
));
}
}
_ => {
return Err(SignatureError::BadElement(
param.to_owned(),
ValueError::InvalidVMContext,
));
}
}
} else {
return Err(SignatureError::BadSignature);
}
for param in param_iter {
let value_ty =
to_lucet_value(param).map_err(|e| SignatureError::BadElement(param.clone(), e))?;
params.push(value_ty);
}
let ret_ty: Option<ValueType> = match value.returns.as_slice() {
&[] => None,
&[ref ret_ty] => {
let value_ty = to_lucet_value(ret_ty)
.map_err(|e| SignatureError::BadElement(ret_ty.clone(), e))?;
Some(value_ty)
}
_ => {
return Err(SignatureError::BadSignature);
}
};
Ok(Signature { params, ret_ty })
}