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
use crate::{
attr_derivation::{
attr_params, find_attr_slice, new_attr, new_native_fun, new_simple_type, new_var,
},
parser::ast::{Definition, FunctionName, ModuleDefinition, ModuleMember, Visibility},
shared::{CompilationEnv, NamedAddressMap},
};
use move_ir_types::location::sp;
use move_symbol_pool::Symbol;
const CONTRACT_ATTR: &str = "contract";
const CALLABLE_ATTR: &str = "callable";
const EXTERNAL_ATTR: &str = "external";
pub(crate) fn derive_for_evm(
_env: &mut CompilationEnv,
_address_map: &NamedAddressMap,
def: &mut Definition,
) {
if let Definition::Module(mod_def) = def {
derive_module_for_evm(mod_def)
}
}
fn derive_module_for_evm(mod_def: &mut ModuleDefinition) {
if find_attr_slice(&mod_def.attributes, CONTRACT_ATTR).is_none() {
return;
}
let mut new_funs = vec![];
for mem in &mod_def.members {
if let ModuleMember::Function(fun_def) = mem {
if let Some(attr) = find_attr_slice(&fun_def.attributes, CALLABLE_ATTR) {
let loc = attr.loc;
let call_name =
FunctionName(sp(loc, Symbol::from(format!("call_{}", fun_def.name))));
let mut sign = fun_def.signature.clone();
sign.parameters.insert(
0,
(
new_var(loc, "_target"),
new_simple_type(loc, "address", vec![]),
),
);
let attrs = sp(
loc,
vec![new_attr(
loc,
EXTERNAL_ATTR,
attr_params(attr).into_iter().cloned().collect(),
)],
);
new_funs.push(new_native_fun(
loc,
call_name,
attrs,
Visibility::Public(loc),
None,
sign,
));
}
}
}
for fun_def in new_funs {
mod_def.members.push(ModuleMember::Function(fun_def))
}
}