Skip to main content

luaur_code_gen/functions/
to_string_ir_dump_alt_g.rs

1extern crate alloc;
2
3use crate::enums::include_cfg_info::IncludeCfgInfo;
4use crate::enums::include_reg_flow_info::IncludeRegFlowInfo;
5use crate::enums::include_use_info::IncludeUseInfo;
6use crate::enums::ir_block_kind::IrBlockKind;
7use crate::functions::append::append;
8use crate::functions::is_pseudo::is_pseudo;
9use crate::functions::to_string_detailed_ir_dump::to_string_detailed as to_string_detailed_inst;
10use crate::functions::to_string_detailed_ir_dump_alt_b::to_string_detailed as to_string_detailed_block;
11use crate::functions::to_string_ir_dump_alt_c::to_string_ir_to_string_context_ir_block_u32 as to_string_block;
12use crate::records::ir_function::IrFunction;
13use crate::records::ir_to_string_context::ir_to_string_context;
14use alloc::string::String;
15use core::ffi::c_void;
16
17const K_BLOCK_FLAG_SAFE_ENV_CHECK: u8 = 1 << 0;
18
19pub fn to_string(function: &mut IrFunction, include_use_info: IncludeUseInfo) -> String {
20    let mut result = String::new();
21
22    {
23        let mut ctx = ir_to_string_context {
24            result: &mut result,
25            blocks: &function.blocks,
26            constants: &function.constants,
27            cfg: &function.cfg,
28            vm_exit_info: &function.vm_exit_info,
29            proto: function.proto as *mut c_void,
30        };
31
32        for i in 0..function.blocks.len() {
33            let block = function.blocks[i];
34
35            if block.kind == IrBlockKind::Dead {
36                continue;
37            }
38
39            to_string_detailed_block(
40                &mut ctx,
41                &block,
42                i as u32,
43                include_use_info,
44                IncludeCfgInfo::Yes,
45                IncludeRegFlowInfo::Yes,
46            );
47
48            if block.start == !0u32 {
49                append(&mut ctx.result, format_args!(" *empty*\n\n"));
50                continue;
51            }
52
53            if (block.flags & K_BLOCK_FLAG_SAFE_ENV_CHECK) != 0 {
54                append(
55                    &mut ctx.result,
56                    format_args!("   implicit CHECK_SAFE_ENV exit({})\n", block.startpc),
57                );
58            }
59
60            // To allow dumping blocks that are still being constructed, we can't rely on
61            // terminator and need a bounds check
62            let mut index = block.start;
63            while index <= block.finish && (index as usize) < function.instructions.len() {
64                let inst = &mut function.instructions[index as usize];
65
66                // Skip pseudo instructions unless they are still referenced
67                if is_pseudo(inst.cmd) && inst.use_count == 0 {
68                    index += 1;
69                    continue;
70                }
71
72                append(&mut ctx.result, format_args!(" "));
73                to_string_detailed_inst(&mut ctx, &block, i as u32, inst, index, include_use_info);
74
75                index += 1;
76            }
77
78            if block.expected_next_block != !0u32 {
79                append(&mut ctx.result, format_args!("; glued to: "));
80                let glued = function.blocks[block.expected_next_block as usize];
81                to_string_block(&mut ctx, &glued, block.expected_next_block);
82                append(&mut ctx.result, format_args!("\n"));
83            }
84
85            append(&mut ctx.result, format_args!("\n"));
86        }
87    }
88
89    result
90}