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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// EXTERNAL_CRATE_REQUIRED: libc - provides FILE and fprintf for native CLI output
use crate::macros::write_name::WRITE_NAME;
use crate::macros::write_pair::WRITE_PAIR;
use crate::macros::write_pair_string::WRITE_PAIR_STRING;
use luaur_code_gen::records::function_stats::FunctionStats;
pub fn serialize_function_stats(fp: *mut core::ffi::c_void, stats: &FunctionStats) {
unsafe {
extern "C" {
fn fprintf(
stream: *mut core::ffi::c_void,
format: *const core::ffi::c_char,
...
) -> core::ffi::c_int;
}
fprintf(fp, c" {\n".as_ptr());
// The macros WRITE_PAIR_STRING, WRITE_PAIR, and WRITE_NAME are defined in this crate
// and they internally call libc::fprintf. Since we cannot rely on the 'libc' crate
// being linked, we must ensure the macros use the local extern "C" fprintf or
// we must provide a wrapper. However, the macros are already translated and
// fixed in the crate. Based on the example 'serializeBlockLinearizationStats',
// we define fprintf locally.
macro_rules! local_fprintf {
($($arg:tt)*) => {
fprintf($($arg)*)
};
}
// We redefine the logic of the macros here to avoid the unresolved 'libc' dependency
// in the pre-translated macros, or we assume the environment provides a way to call it.
// Given the constraints and the failure, we will implement the serialization manually
// using the local fprintf to ensure it compiles.
fprintf(
fp,
c" \"name\": \"%s\",\n".as_ptr(),
stats.name.as_ptr(),
);
fprintf(
fp,
c" \"line\": %d,\n".as_ptr(),
stats.line,
);
fprintf(
fp,
c" \"bcode_count\": %u,\n".as_ptr(),
stats.bcode_count,
);
fprintf(
fp,
c" \"ir_count\": %u,\n".as_ptr(),
stats.ir_count,
);
fprintf(
fp,
c" \"asm_count\": %u,\n".as_ptr(),
stats.asm_count,
);
fprintf(
fp,
c" \"asm_size\": %u,\n".as_ptr(),
stats.asm_size,
);
fprintf(fp, c" \"bytecode_summary\": ".as_ptr());
let nesting_limit = stats.bytecode_summary.len();
if nesting_limit == 0 {
fprintf(fp, c"[]".as_ptr());
} else {
fprintf(fp, c"[\n".as_ptr());
for i in 0..nesting_limit {
let counts = &stats.bytecode_summary[i];
fprintf(fp, c" [".as_ptr());
for j in 0..counts.len() {
fprintf(fp, c"%u".as_ptr(), counts[j]);
if j < counts.len() - 1 {
fprintf(fp, c", ".as_ptr());
}
}
fprintf(fp, c"]".as_ptr());
if i < nesting_limit - 1 {
fprintf(fp, c",\n".as_ptr());
}
}
fprintf(fp, c"\n ]".as_ptr());
}
fprintf(fp, c"\n }".as_ptr());
}
}