///|
pub fn render_module_opcodes(report : ModuleOpcodeReport, top : Int) -> String {
let out = StringBuilder()
out.write_string(
"MODULE FUNCTION OPCODE STATISTICS\n\nInput: \{report.file_size} B; SHA-256 \{report.sha256}\nImported functions: \{report.imported_function_count}; local functions: \{report.local_function_count}\n",
)
match report.code_section {
None => out.write_string("No code section; no code/count ranges.\n")
Some(code) => {
out.write_string(
"Code section: file offset \{code.offset}, total \{code.total_size} B, payload \{code.payload_size} B\n",
)
if report.local_function_count == 0 {
out.write_string(
"Explicit empty code section; its header and zero-count encoding are retained.\n",
)
}
}
}
match report.count_encoding {
Some(span) =>
out.write_string(
"Function count encoding: file offset \{span.file_offset}, size \{span.size} B\n",
)
None => ()
}
let code_size = match report.code_section {
Some(code) => code.total_size
None => 0
}
out.write_string(
"Code bytes: \{code_size} = header \{report.code_header_bytes} + count encoding \{report.count_encoding_bytes} + body prefixes \{report.body_prefix_bytes} + locals \{report.locals_encoding_bytes} + instructions \{report.instruction_bytes}\n",
)
out.write_string(
"Instructions: \{report.instruction_count}; complete instruction encoding bytes: \{report.instruction_bytes}\n",
)
let shown = top.max(0).min(report.groups.length())
out.write_string(
"\nOPCODE GROUPS: showing \{shown} of \{report.groups.length()} (encoded bytes descending, count descending, mnemonic ascending)\nMNEMONIC COUNT FUNCTIONS ENCODED BYTES\n",
)
if report.groups.is_empty() {
out.write_string(
"No function instructions recorded. This is not full function-termination or semantic validation.\n",
)
}
for i in 0.. Json {
let root : Map[String, Json] = Map([])
root.set("format", Json::string("moonsize-module-opcodes"))
root.set("schema_version", int_json(1))
root.set("file_size", int_json(report.file_size))
root.set("sha256", Json::string(report.sha256))
root.set(
"code_section",
match report.code_section {
None => Json::null()
Some(code) => {
let value : Map[String, Json] = Map([])
value.set("id", int_json(code.id))
value.set("kind", Json::string(code.kind.name()))
value.set("offset", int_json(code.offset))
value.set("payload_size", int_json(code.payload_size))
value.set("total_size", int_json(code.total_size))
Json::object(value)
}
},
)
root.set(
"count_encoding",
match report.count_encoding {
Some(span) => function_instruction_range_json(span)
None => Json::null()
},
)
for
(key, value) in [
("imported_function_count", report.imported_function_count),
("local_function_count", report.local_function_count),
("code_header_bytes", report.code_header_bytes),
("count_encoding_bytes", report.count_encoding_bytes),
("body_prefix_bytes", report.body_prefix_bytes),
("locals_encoding_bytes", report.locals_encoding_bytes),
("instruction_bytes", report.instruction_bytes),
("instruction_count", report.instruction_count),
] {
root.set(key, int_json(value))
}
root.set(
"groups",
Json::array(
report.groups.map(fn(group) {
let row : Map[String, Json] = Map([])
row.set("mnemonic", Json::string(group.mnemonic))
row.set("count", int_json(group.count))
row.set("encoded_bytes", int_json(group.encoded_bytes))
row.set("function_count", int_json(group.function_count))
Json::object(row)
}),
),
)
root.set(
"functions",
Json::array(
report.functions.map(fn(summary) {
let row : Map[String, Json] = Map([])
let stat = summary.stat
let value : Map[String, Json] = Map([])
value.set("index", int_json(stat.index))
value.set(
"name",
match stat.raw_name {
Some(_) => Json::string(stat.name)
None => Json::null()
},
)
value.set("raw_name", path_optional_string(stat.raw_name))
value.set("display_name", Json::string(stat.name))
value.set("module_name", Json::string(stat.module_name))
value.set("body_size", int_json(stat.body_size))
value.set("total_size", int_json(stat.total_size))
value.set("offset", int_json(stat.offset))
row.set("stat", Json::object(value))
row.set(
"locals_encoding",
function_instruction_range_json(summary.locals_encoding),
)
row.set("instruction_count", int_json(summary.instruction_count))
row.set("instruction_bytes", int_json(summary.instruction_bytes))
Json::object(row)
}),
),
)
root.set("scope", Json::string(report.scope))
Json::object(root)
}
///|
pub fn render_module_opcodes_json(report : ModuleOpcodeReport) -> String {
module_opcodes_json_value(report).stringify(indent=2) + "\n"
}