wasmer_cli/c_gen/
staticlib_header.rs1use wasmer_compiler::types::symbols::{Symbol, SymbolRegistry};
4use wasmer_types::ModuleInfo;
5
6use super::{CStatement, CType, generate_c};
7
8fn gen_helper_functions(atom_name: &str, module_name: &str) -> String {
10 format!("
11 wasm_module_t* wasmer_object_module_new_{atom_name}(wasm_store_t* store, const char* wasm_name) {{
12 // wasm_name intentionally unused for now: will be used in the future.
13 wasm_byte_vec_t module_byte_vec = {{
14 .size = module_bytes_len_{atom_name},
15 .data = (char*)&{module_name}[0],
16 }};
17 wasm_module_t* module = wasm_module_deserialize(store, &module_byte_vec);
18
19 return module;
20 }}
21 ")
22}
23
24pub fn generate_header_file(
26 atom_name: &str,
27 module_info: &ModuleInfo,
28 symbol_registry: &dyn SymbolRegistry,
29 metadata_length: usize,
30) -> String {
31 let mut c_statements = vec![
32 CStatement::LiteralConstant {
33 value: "#include \"wasmer.h\"\n#include <stdlib.h>\n#include <string.h>\n\n"
34 .to_string(),
35 },
36 CStatement::LiteralConstant {
37 value: "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n".to_string(),
38 },
39 CStatement::Declaration {
40 name: format!("module_bytes_len_{atom_name}"),
41 is_extern: false,
42 is_const: true,
43 ctype: CType::U32,
44 definition: Some(Box::new(CStatement::LiteralConstant {
45 value: metadata_length.to_string(),
46 })),
47 },
48 CStatement::Declaration {
49 name: symbol_registry.symbol_to_name(Symbol::Metadata),
50 is_extern: true,
51 is_const: true,
52 ctype: CType::Array {
53 inner: Box::new(CType::U8),
54 },
55 definition: None,
56 },
57 ];
58 let function_declarations = module_info
59 .functions
60 .iter()
61 .filter_map(|(f_index, sig_index)| {
62 Some((module_info.local_func_index(f_index)?, sig_index))
63 })
64 .map(|(function_local_index, _sig_index)| {
65 let function_name =
66 symbol_registry.symbol_to_name(Symbol::LocalFunction(function_local_index));
67 CStatement::Declaration {
69 name: function_name,
70 is_extern: true,
71 is_const: false,
72 ctype: CType::Function {
73 arguments: vec![CType::Void],
74 return_value: None,
75 },
76 definition: None,
77 }
78 });
79 c_statements.push(CStatement::LiteralConstant {
80 value: r#"
81// Compiled Wasm function pointers ordered by function index: the order they
82// appeared in in the Wasm module.
83"#
84 .to_string(),
85 });
86 c_statements.extend(function_declarations);
87
88 let func_trampoline_declarations =
89 module_info
90 .signatures
91 .iter()
92 .map(|(sig_index, _func_type)| {
93 let function_name =
94 symbol_registry.symbol_to_name(Symbol::FunctionCallTrampoline(sig_index));
95
96 CStatement::Declaration {
97 name: function_name,
98 is_extern: true,
99 is_const: false,
100 ctype: CType::Function {
101 arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
102 return_value: None,
103 },
104 definition: None,
105 }
106 });
107 c_statements.push(CStatement::LiteralConstant {
108 value: r#"
109// Trampolines (functions by which we can call into Wasm) ordered by signature.
110// There is 1 trampoline per function signature in the order they appear in
111// the Wasm module.
112"#
113 .to_string(),
114 });
115 c_statements.extend(func_trampoline_declarations);
116
117 let dyn_func_declarations = module_info
118 .functions
119 .keys()
120 .take(module_info.num_imported_functions)
121 .map(|func_index| {
122 let function_name =
123 symbol_registry.symbol_to_name(Symbol::DynamicFunctionTrampoline(func_index));
124 CStatement::Declaration {
126 name: function_name,
127 is_extern: true,
128 is_const: false,
129 ctype: CType::Function {
130 arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
131 return_value: None,
132 },
133 definition: None,
134 }
135 });
136 c_statements.push(CStatement::LiteralConstant {
137 value: r#"
138// Dynamic trampolines are per-function and are used for each function where
139// the type signature is not known statically. In this case, this corresponds to
140// the imported functions.
141"#
142 .to_string(),
143 });
144 c_statements.extend(dyn_func_declarations);
145
146 c_statements.push(CStatement::TypeDef {
147 source_type: CType::Function {
148 arguments: vec![CType::void_ptr(), CType::void_ptr(), CType::void_ptr()],
149 return_value: None,
150 },
151 new_name: "dyn_func_trampoline_t".to_string(),
152 });
153
154 c_statements.push(CStatement::LiteralConstant {
155 value: gen_helper_functions(atom_name, &symbol_registry.symbol_to_name(Symbol::Metadata)),
156 });
157
158 c_statements.push(CStatement::LiteralConstant {
159 value: "\n#ifdef __cplusplus\n}\n#endif\n\n".to_string(),
160 });
161
162 generate_c(&c_statements)
163}