///|
pub fn Module::with_custom_secs(
self : Module,
custom_secs : Array[CustomSec],
) -> Module {
Module::{ ..self, custom_secs, }
}
///|
pub fn Module::with_name_sec(self : Module, name_sec : NameSec) -> Module {
Module::{ ..self, name_sec: Some(name_sec), raw_name_sec_payload: None, }
}
///|
pub fn Module::without_name_sec(self : Module) -> Module {
Module::{ ..self, name_sec: None, raw_name_sec_payload: None, }
}
///|
pub fn Module::with_raw_name_sec_payload(
self : Module,
payload : Bytes,
) -> Module {
Module::{ ..self, raw_name_sec_payload: Some(payload), }
}
///|
pub fn Module::with_compiler_fact_custom_section(
self : Module,
compiler_fact_custom_section : @representation.CompilerFactCustomSection,
) -> Module {
Module::{
..self,
compiler_fact_custom_section: Some(compiler_fact_custom_section),
}
}
///|
pub fn Module::without_compiler_fact_custom_section(self : Module) -> Module {
Module::{ ..self, compiler_fact_custom_section: None, }
}
///|
pub fn Module::with_type_sec(self : Module, type_sec : TypeSec) -> Module {
Module::{
..self,
type_sec: Some(type_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_import_sec(self : Module, import_sec : ImportSec) -> Module {
Module::{
..self,
import_sec: Some(import_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_func_annotation_sec(
self : Module,
func_annotation_sec : FuncAnnotationSec,
) -> Module {
Module::{ ..self, func_annotation_sec: Some(func_annotation_sec), }
}
///|
pub fn Module::with_func_sec(self : Module, func_sec : FuncSec) -> Module {
Module::{
..self,
func_sec: Some(func_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_table_sec(self : Module, table_sec : TableSec) -> Module {
Module::{
..self,
table_sec: Some(table_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_mem_sec(self : Module, mem_sec : MemSec) -> Module {
Module::{
..self,
mem_sec: Some(mem_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_tag_sec(self : Module, tag_sec : TagSec) -> Module {
Module::{ ..self, tag_sec: Some(tag_sec), }
}
///|
pub fn Module::with_stringrefs_sec(
self : Module,
stringrefs_sec : StringRefsSec,
) -> Module {
Module::{
..self,
stringrefs_sec: Some(stringrefs_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_global_sec(self : Module, global_sec : GlobalSec) -> Module {
Module::{
..self,
global_sec: Some(global_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_export_sec(self : Module, export_sec : ExportSec) -> Module {
Module::{ ..self, export_sec: Some(export_sec), }
}
///|
pub fn Module::with_start_sec(self : Module, start_sec : StartSec) -> Module {
Module::{ ..self, start_sec: Some(start_sec), }
}
///|
pub fn Module::with_elem_sec(self : Module, elem_sec : ElemSec) -> Module {
Module::{ ..self, elem_sec: Some(elem_sec), }
}
///|
pub fn Module::with_data_cnt_sec(
self : Module,
data_cnt_sec : DataCntSec,
) -> Module {
Module::{ ..self, data_cnt_sec: Some(data_cnt_sec), }
}
///|
pub fn Module::with_code_sec(self : Module, code_sec : CodeSec) -> Module {
Module::{
..self,
code_sec: Some(code_sec),
compiler_fact_custom_section: None,
}
}
///|
pub fn Module::with_data_sec(self : Module, data_sec : DataSec) -> Module {
Module::{ ..self, data_sec: Some(data_sec), }
}
///|
priv struct ModuleDebugContext {
subtypes : Array[SubType]
_func_type_idxs : Array[TypeIdx]
func_imports : Array[Import]
_tables : Array[TableType]
mems : Array[MemType]
_globals : Array[GlobalType]
_tags : Array[TagType]
}
///|
fn md_build_context(mod : Module) -> ModuleDebugContext {
let subtypes : Array[SubType] = []
match mod.type_sec {
Some(TypeSec(rec_types)) =>
for rec_type in rec_types {
match rec_type {
SingleRecType(subtype) => subtypes.push(subtype)
GroupRecType(group) =>
for subtype in group {
subtypes.push(subtype)
}
}
}
None => ()
}
let func_type_idxs : Array[TypeIdx] = []
let func_imports : Array[Import] = []
let tables : Array[TableType] = []
let mems : Array[MemType] = []
let globals : Array[GlobalType] = []
let tags : Array[TagType] = []
match mod.import_sec {
Some(ImportSec(imports)) =>
for import_ in imports {
match import_ {
Import(_, _, FuncExternType(type_idx)) => {
func_type_idxs.push(type_idx)
func_imports.push(import_)
}
Import(_, _, TableExternType(table_type)) => tables.push(table_type)
Import(_, _, MemExternType(mem_type)) => mems.push(mem_type)
Import(_, _, GlobalExternType(global_type)) =>
globals.push(global_type)
Import(_, _, TagExternType(tag_type)) => tags.push(tag_type)
}
}
None => ()
}
match mod.func_sec {
Some(FuncSec(type_idxs)) =>
for type_idx in type_idxs {
func_type_idxs.push(type_idx)
}
None => ()
}
match mod.table_sec {
Some(TableSec(defs)) =>
for table in defs {
let Table(table_type, _) = table
tables.push(table_type)
}
None => ()
}
match mod.mem_sec {
Some(MemSec(defs)) =>
for mem_type in defs {
mems.push(mem_type)
}
None => ()
}
match mod.global_sec {
Some(GlobalSec(defs)) =>
for global in defs {
let Global(global_type, _) = global
globals.push(global_type)
}
None => ()
}
match mod.tag_sec {
Some(TagSec(defs)) =>
for tag_type in defs {
tags.push(tag_type)
}
None => ()
}
{
subtypes,
_func_type_idxs: func_type_idxs,
func_imports,
_tables: tables,
mems,
_globals: globals,
_tags: tags,
}
}
///|
fn md_resolve_subtype(ctx : ModuleDebugContext, idx : TypeIdx) -> SubType? {
match idx {
TypeIdx(i) => ctx.subtypes.get(i.reinterpret_as_int())
RecIdx(_) => None
}
}
///|
fn md_resolve_functype(ctx : ModuleDebugContext, idx : TypeIdx) -> FuncType? {
match md_resolve_subtype(ctx, idx) {
Some(subtype) =>
match subtype.get_comptype() {
FuncCompType(params, results) => Some(FuncType::new(params, results))
_ => None
}
None => None
}
}
///|
fn md_format_type_idx(ctx : ModuleDebugContext, idx : TypeIdx) -> String {
pretty_resolved_type_idx(ctx.subtypes, idx)
}
///|
fn _md_format_heap_type(
ctx : ModuleDebugContext,
heap_type : HeapType,
) -> String {
match heap_type {
HeapType(type_idx) => md_format_type_idx(ctx, type_idx)
_ => pretty_heap_type(heap_type)
}
}
///|
fn _md_format_mem_idx(ctx : ModuleDebugContext, idx : MemIdx) -> String {
let MemIdx(i) = idx
let raw = idx.to_string()
match ctx.mems.get(i.reinterpret_as_int()) {
Some(mem_type) => raw + " : " + mem_type.to_string()
None => raw + " : "
}
}
///|
fn md_indent(out : StringBuilder, depth : Int) -> Unit {
for _ in 0.. Unit {
md_indent(out, depth)
out.write_string(line)
out.write_char('\n')
}
///|
fn md_imported_func_count(ctx : ModuleDebugContext) -> Int {
ctx.func_imports.length()
}
///|
pub fn Module::pretty_print_func(self : Module, func_idx : FuncIdx) -> String {
let ctx = md_build_context(self)
let FuncIdx(i) = func_idx
let abs_idx = i.reinterpret_as_int()
let imported = md_imported_func_count(ctx)
if abs_idx < imported {
let out = StringBuilder::new()
md_write_line(out, 0, "func abs[\{abs_idx}] import")
match ctx.func_imports.get(abs_idx) {
Some(Import(module_name, field_name, FuncExternType(type_idx))) => {
md_write_line(out, 2, "module: \"" + module_name.0.to_owned() + "\"")
md_write_line(out, 2, "field: \"" + field_name.0.to_owned() + "\"")
md_write_line(out, 2, "type_idx: " + md_format_type_idx(ctx, type_idx))
}
_ => md_write_line(out, 2, "")
}
return out.to_string()
}
self.pretty_print_defined_func((abs_idx - imported).reinterpret_as_uint())
}
///|
pub fn Module::pretty_print_defined_func(
self : Module,
def_idx : UInt,
) -> String {
let ctx = md_build_context(self)
let def_idx_i = def_idx.reinterpret_as_int()
let imported = md_imported_func_count(ctx)
let abs_idx = imported + def_idx_i
let out = StringBuilder::new()
let type_idx = match self.func_sec {
Some(FuncSec(type_idxs)) => type_idxs.get(def_idx_i)
None => None
}
let func = match self.code_sec {
Some(CodeSec(funcs)) => funcs.get(def_idx_i)
None => None
}
match (type_idx, func) {
(Some(type_idx), Some(func)) => {
md_write_line(out, 0, "func code[\{def_idx_i}] abs[\{abs_idx}]")
md_write_line(out, 2, "type_idx: " + md_format_type_idx(ctx, type_idx))
let FuncType(params, results) = match md_resolve_functype(ctx, type_idx) {
Some(func_type) => func_type
None => FuncType::new([], [])
}
md_write_line(out, 2, "params: " + pretty_result_type(params))
md_write_line(out, 2, "results: " + pretty_result_type(results))
match func {
Func(grouped_locals, body) => {
let full_locals = match
FunctionLocals::from_local_decls(params, grouped_locals) {
Ok(locals) => locals.all_locals()
Err(err) => {
md_write_line(out, 2, "locals_error: " + err)
Locals::from_types(params)
}
}
md_write_line(out, 2, "locals:")
if full_locals.is_empty() {
md_write_line(out, 4, "")
} else {
for i in 0.. md_write_line(out, 0, "func code[\{def_idx_i}] ")
}
out.to_string()
}