witx_codegen/zig/
function.rs1use std::io::Write;
2
3use super::*;
4
5impl ZigGenerator {
6 pub fn define_func<T: Write>(
7 w: &mut PrettyWriter<T>,
8 module_name: &str,
9 func_witx: &witx::Function,
10 ) -> Result<(), Error> {
11 assert_eq!(func_witx.abi, witx::Abi::Preview1);
12 let name = func_witx.name.as_str().to_string();
13 let params_witx = &func_witx.params;
14 let mut params = vec![];
15 for param_witx in params_witx {
16 let param_name = param_witx.name.as_str();
17 let param_type = ASType::from(¶m_witx.tref);
18 params.push((param_name.to_string(), param_type));
19 }
20
21 let results_witx = &func_witx.results;
22 assert_eq!(results_witx.len(), 1);
23 let result_witx = &results_witx[0];
24 let result = ASType::from(&result_witx.tref);
25 let result = match result {
26 ASType::Result(result) => result,
27 _ => unreachable!(),
28 };
29
30 let ok_type = result.ok_type.clone();
31
32 let docs = &func_witx.docs;
33 if !docs.is_empty() {
34 Self::write_docs(w, docs)?;
35 }
36
37 let mut params_decomposed = vec![];
38
39 for param in ¶ms {
40 let mut decomposed = param.1.decompose(¶m.0, false);
41 params_decomposed.append(&mut decomposed);
42 }
43
44 let mut results = vec![];
45 if let ASType::Tuple(tuple_members) = ok_type.as_ref().leaf() {
48 for (i, tuple_member) in tuple_members.iter().enumerate() {
49 let name = format!("result{}_ptr", i);
50 results.push((name, tuple_member.type_.clone()));
51 }
52 } else {
53 let name = "result_ptr";
54 results.push((name.to_string(), ok_type));
55 }
56 let mut results_decomposed = vec![];
57 for result in &results {
58 let mut decomposed = result.1.decompose(&result.0, true);
59 results_decomposed.append(&mut decomposed);
60 }
61
62 Self::define_func_raw(
63 w,
64 module_name,
65 &name,
66 ¶ms_decomposed,
67 &results_decomposed,
68 &result,
69 )?;
70
71 let signature_witx = func_witx.wasm_signature(witx::CallMode::DefinedImport);
72 let params_count_witx = signature_witx.params.len() + signature_witx.results.len();
73 assert_eq!(
74 params_count_witx,
75 params_decomposed.len() + results_decomposed.len() + 1
76 );
77
78 Ok(())
79 }
80
81 fn define_func_raw<T: Write>(
82 w: &mut PrettyWriter<T>,
83 module_name: &str,
84 name: &str,
85 params_decomposed: &[ASTypeDecomposed],
86 results_decomposed: &[ASTypeDecomposed],
87 result: &ASResult,
88 ) -> Result<(), Error> {
89 w.indent()?
90 .write(format!("pub extern \"{}\" fn {}(", module_name, name))?;
91 if !params_decomposed.is_empty() || !results_decomposed.is_empty() {
92 w.eol()?;
93 }
94 for param in params_decomposed.iter().chain(results_decomposed.iter()) {
95 w.write_line_continued(format!(
96 "{}: {},",
97 param.name.as_var(),
98 param.type_.as_lang(),
99 ))?;
100 }
101 w.write_line(format!(") callconv(.c) {};", result.error_type.as_lang()))?;
102 w.eob()?;
103 Ok(())
104 }
105}