1use anstream::println;
2use eyre::Result;
3use owo_colors::OwoColorize;
4use tinywasm::types::{ExternalKind, ImportKind};
5
6use crate::cli::ModuleInputArgs;
7use crate::load::load_module;
8
9pub fn run(args: ModuleInputArgs) -> Result<()> {
10 let loaded = load_module(&args.module)?;
11 let module = loaded.module;
12
13 let imported_func_count =
14 module.imports.iter().filter(|import| matches!(import.kind, ImportKind::Function(_))).count() as u32;
15
16 for (func_idx, func) in module.funcs.iter().enumerate() {
17 let global_idx = imported_func_count + func_idx as u32;
18
19 let exports = module
20 .exports
21 .iter()
22 .filter(|export| export.kind == ExternalKind::Func && export.index == global_idx)
23 .map(|export| export.name.as_ref())
24 .collect::<Vec<_>>();
25
26 let header = format!("func[{func_idx}]").blue().bold().to_string();
27 if exports.is_empty() {
28 println!("{header}");
29 } else {
30 println!("{header} {}", format!("exports={}", format!("{exports:?}").cyan()).bright_black());
31 }
32
33 for (ip, instr) in func.instructions.iter().enumerate() {
34 let instr = print_instr(instr);
35 println!(" {}: {}", print_ip(ip), instr);
36 }
37 println!();
38 }
39
40 Ok(())
41}
42
43fn print_ip(ip: usize) -> String {
44 let s = format!("{ip:04}");
45 let first_non_zero = s.find(|c| c != '0').unwrap_or(s.len() - 1);
46
47 format!(
48 "{}{}",
49 &s[..first_non_zero].to_string().bright_black().dimmed(),
50 &s[first_non_zero..].to_string().bright_black()
51 )
52}
53
54fn print_instr(instr: &tinywasm::types::Instruction) -> String {
55 let instr = format!("{instr:?}");
56 let Some(split) = instr.find(['(', ' ', '{']) else {
57 return instr.bold().to_string();
58 };
59
60 let (name, rest) = instr.split_at(split);
61
62 let rest = rest
63 .replace('(', &"(".bright_black().to_string())
64 .replace(')', &")".bright_black().to_string())
65 .replace('{', &"{".bright_black().to_string())
66 .replace('}', &"}".bright_black().to_string())
67 .replace(',', &",".bright_black().to_string())
68 .replace(':', &":".bright_black().to_string());
69
70 format!("{}{}", name.bold(), rest)
71}