///|
pub fn render_function_locals(
report : FunctionLocalsReport,
top : Int,
) -> String {
let out = StringBuilder()
out.write_string(
"FUNCTION LOCAL DECLARATIONS\n\nTarget: #\{report.target.index} " +
search_terminal_string(report.target.name) +
" (local)\n",
)
out.write_string(
"Input: \{report.file_size} B; SHA-256 \{report.sha256}\nGroups: \{report.group_count}; declared variables (excluding parameters): \{report.declared_count}\n",
)
out.write_string(
"Entry: file offset \{report.entry.file_offset}, size \{report.entry.size} B\nBody: file offset \{report.body.file_offset}, size \{report.body.size} B\nLocals: file offset \{report.locals_encoding.file_offset}, size \{report.locals_encoding.size} B\nGroup count: file offset \{report.group_count_encoding.file_offset}, size \{report.group_count_encoding.size} B\nBody remainder (undecoded): file offset \{report.body_remainder.file_offset}, size \{report.body_remainder.size} B\n",
)
out.write_string(
"Encoded bytes: \{report.entry.size} = prefix \{report.prefix.size} + body \{report.body.size}\nBody bytes: \{report.body.size} = locals \{report.locals_encoding.size} + undecoded remainder \{report.body_remainder.size}\nLocals bytes: \{report.locals_encoding.size} = group count \{report.group_count_encoding.size} + quantities \{report.quantity_encoding_bytes} + types \{report.type_encoding_bytes}\n",
)
let shown = top.max(0).min(report.groups.length())
out.write_string(
"\nGROUPS: showing \{shown} of \{report.group_count}\nGROUP QUANTITY DECLARED ORDINALS (EXCLUDING PARAMETERS) TYPE HEX FILE RANGE SIZE\n",
)
if report.groups.is_empty() {
out.write_string(
"Zero declaration groups; the group-count field is still encoded. Parameter count is not inspected.\n",
)
} else if report.declared_count == 0UL {
out.write_string("Declaration groups exist, but all quantities are zero.\n")
}
for i in 0.. label
None => "unknown"
}) +
" " +
group.type_hex +
" [\{group.encoding.file_offset},\{group.encoding.file_offset + group.encoding.size}) \{group.encoding.size}\n",
)
}
out.write_string("\n" + report.scope + "\n")
out.to_string()
}
///|
pub fn render_function_locals_json(report : FunctionLocalsReport) -> String {
function_locals_json_value(report).stringify(indent=2) + "\n"
}
///|
fn function_locals_json_value(report : FunctionLocalsReport) -> Json {
let root : Map[String, Json] = Map([])
root.set("format", Json::string("moonsize-function-locals"))
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("target", path_node_json(report.target))
root.set("entry", function_instruction_range_json(report.entry))
root.set("prefix", function_instruction_range_json(report.prefix))
root.set("body", function_instruction_range_json(report.body))
root.set(
"locals_encoding",
function_instruction_range_json(report.locals_encoding),
)
root.set(
"group_count_encoding",
function_instruction_range_json(report.group_count_encoding),
)
root.set(
"body_remainder",
function_instruction_range_json(report.body_remainder),
)
root.set("group_count", int_json(report.group_count))
root.set(
"declared_count_decimal",
Json::string(report.declared_count.to_string()),
)
root.set("quantity_encoding_bytes", int_json(report.quantity_encoding_bytes))
root.set("type_encoding_bytes", int_json(report.type_encoding_bytes))
root.set(
"groups",
Json::array(
report.groups.map(fn(group) {
let row : Map[String, Json] = Map([])
row.set("group_index", int_json(group.group_index))
row.set("quantity", Json::number(group.quantity.to_double()))
row.set(
"declared_ordinal_start_decimal",
Json::string(group.declared_ordinal_start.to_string()),
)
row.set(
"declared_ordinal_end_decimal",
Json::string(group.declared_ordinal_end.to_string()),
)
row.set("encoding", function_instruction_range_json(group.encoding))
row.set(
"quantity_encoding",
function_instruction_range_json(group.quantity_encoding),
)
row.set(
"type_encoding",
function_instruction_range_json(group.type_encoding),
)
row.set("type_hex", Json::string(group.type_hex))
row.set(
"type_label",
match group.type_label {
Some(label) => Json::string(label)
None => Json::null()
},
)
Json::object(row)
}),
),
)
root.set("scope", Json::string(report.scope))
Json::object(root)
}