Skip to main content

luaur_bytecode_cli/functions/
serialize_function_summary.rs

1use core::ffi::c_void;
2use std::ffi::CString;
3
4use luaur_code_gen::records::function_bytecode_summary::FunctionBytecodeSummary;
5
6/// Source: `CLI/src/Bytecode.cpp:185-215` (`serializeFunctionSummary`).
7///
8/// The `%s` fields take C-string pointers. `getSource()`/`getName()` return a
9/// non-NUL-terminated `&str`, so they are copied into NUL-terminated `CString`s
10/// (the C++ uses `std::string::c_str()`) before being handed to `fprintf`.
11pub fn serialize_function_summary(summary: &FunctionBytecodeSummary, fp: *mut c_void) {
12    let nesting_limit = summary.get_nesting_limit();
13    let op_limit = summary.get_op_limit();
14
15    let source = CString::new(summary.get_source().replace('\0', "")).unwrap();
16    let name = CString::new(summary.get_name().replace('\0', "")).unwrap();
17
18    unsafe {
19        // Write opening brace
20        fprintf(fp, c"        {\n".as_ptr());
21        // Write source
22        fprintf(
23            fp,
24            c"            \"source\": \"%s\",\n".as_ptr(),
25            source.as_ptr(),
26        );
27        // Write name
28        fprintf(
29            fp,
30            c"            \"name\": \"%s\",\n".as_ptr(),
31            name.as_ptr(),
32        );
33        // Write line
34        fprintf(
35            fp,
36            c"            \"line\": %d,\n".as_ptr(),
37            summary.get_line(),
38        );
39
40        // Write nestingLimit
41        fprintf(
42            fp,
43            c"            \"nestingLimit\": %u,\n".as_ptr(),
44            nesting_limit,
45        );
46
47        // Write counts array header
48        fprintf(fp, c"            \"counts\": [".as_ptr());
49
50        // Iterate over nesting levels
51        for nesting in 0..=nesting_limit {
52            fprintf(fp, c"\n                [".as_ptr());
53
54            // Iterate over opcodes
55            for i in 0..op_limit {
56                let count = summary.get_count(nesting, i as u8);
57                fprintf(fp, c"%d".as_ptr(), count);
58
59                if i < op_limit - 1 {
60                    fprintf(fp, c", ".as_ptr());
61                }
62            }
63
64            fprintf(fp, c"]".as_ptr());
65
66            if nesting < nesting_limit {
67                fprintf(fp, c",".as_ptr());
68            }
69        }
70
71        // Close counts array and object
72        fprintf(fp, c"\n            ]".as_ptr());
73        fprintf(fp, c"\n        }".as_ptr());
74    }
75}
76
77extern "C" {
78    fn fprintf(stream: *mut c_void, format: *const core::ffi::c_char, ...) -> core::ffi::c_int;
79}