multiversx_sc_meta_lib/ei/
vm_hook_signature.rs1use std::collections::HashMap;
2
3use wasmparser::ValType;
4
5use super::VM_HOOK_SIGNATURES;
6
7#[derive(Debug, Clone)]
8pub struct VmHookSignature {
9 pub name: &'static str,
10 pub params: &'static [ValType],
11 pub returns: Option<ValType>,
12}
13
14impl VmHookSignature {
15 pub const fn new(
16 name: &'static str,
17 params: &'static [ValType],
18 returns: Option<ValType>,
19 ) -> Self {
20 Self {
21 name,
22 params,
23 returns,
24 }
25 }
26
27 pub fn to_wat_func_type_declaration(&self, comment: &str) -> String {
28 let mut sc_wat = String::new();
29 sc_wat.push_str("(type");
30 sc_wat.push_str(comment);
31 sc_wat.push_str(" (func");
32 if !self.params.is_empty() {
33 sc_wat.push_str(" (param");
34 for param in self.params {
35 sc_wat.push(' ');
36 sc_wat.push_str(val_type_to_wat(*param));
37 }
38 sc_wat.push(')');
39 }
40 if let Some(ret) = self.returns {
41 sc_wat.push_str(" (result ");
42 sc_wat.push_str(val_type_to_wat(ret));
43 sc_wat.push(')');
44 }
45 sc_wat.push_str("))");
46 sc_wat
47 }
48}
49
50fn val_type_to_wat(val_type: ValType) -> &'static str {
51 match val_type {
52 ValType::I32 => "i32",
53 ValType::I64 => "i64",
54 _ => panic!("unsupported return type in vm hook signature"),
55 }
56}
57
58pub fn vm_hook_signature_map() -> HashMap<&'static str, VmHookSignature> {
59 let mut map = HashMap::new();
60 for vm_hook in VM_HOOK_SIGNATURES {
61 map.insert(vm_hook.name, vm_hook.clone());
62 }
63 map
64}
65
66pub fn check_vm_hook_signatures(
67 func_name: &str,
68 params: &[ValType],
69 returns: &[ValType],
70 signature_map: &HashMap<&'static str, VmHookSignature>,
71) {
72 let signature = signature_map
73 .get(func_name)
74 .unwrap_or_else(|| panic!("unknown vm hook function: {func_name}"));
75
76 assert_eq!(
77 signature.params, params,
78 "vm hook function {func_name} has invalid parameters"
79 );
80 match signature.returns {
81 Some(ret) => {
82 assert_eq!(
83 returns.len(),
84 1,
85 "vm hook function {func_name} must have exactly one return value"
86 );
87 assert_eq!(
88 returns[0], ret,
89 "vm hook function {func_name} has invalid return type"
90 );
91 }
92 None => {
93 assert!(
94 returns.is_empty(),
95 "vm hook function {func_name} must not have return values"
96 );
97 }
98 }
99}