Skip to main content

jvm_assembler/analyzer/
mod.rs

1use crate::program::*;
2use std::collections::{BTreeSet, HashMap};
3
4/// StackMapTable 分析器框架
5pub struct StackMapAnalyzer<'a> {
6    pub _class_name: String,
7    pub method: &'a JvmMethod,
8    pub label_positions: &'a HashMap<String, i32>,
9}
10
11impl<'a> StackMapAnalyzer<'a> {
12    pub fn new(_class_name: String, method: &'a JvmMethod, label_positions: &'a HashMap<String, i32>) -> Self {
13        Self { _class_name, method, label_positions }
14    }
15
16    /// 分析方法并生成 StackMapTable 帧
17    pub fn analyze(&self) -> Vec<JvmStackMapFrame> {
18        let jump_targets = self.get_jump_targets();
19        if jump_targets.is_empty() {
20            return Vec::new();
21        }
22
23        let mut frames = Vec::new();
24        let mut last_offset = 0;
25        let mut first = true;
26
27        for target_offset in jump_targets {
28            let offset_delta = if first { target_offset as u16 } else { (target_offset - last_offset - 1) as u16 };
29
30            // 基础框架实现:暂时假设为 Full 帧,以保证最大兼容性
31            // 之后可以根据状态差异优化为 Same, Append, Chop 等
32            frames.push(self.generate_full_frame(offset_delta));
33
34            last_offset = target_offset;
35            first = false;
36        }
37
38        frames
39    }
40
41    /// 获取所有的跳转目标偏移量
42    fn get_jump_targets(&self) -> BTreeSet<i32> {
43        let mut targets = BTreeSet::new();
44        for inst in &self.method.instructions {
45            match inst {
46                JvmInstruction::Ifeq { target }
47                | JvmInstruction::Ifne { target }
48                | JvmInstruction::Iflt { target }
49                | JvmInstruction::Ifge { target }
50                | JvmInstruction::Ifgt { target }
51                | JvmInstruction::Ifle { target }
52                | JvmInstruction::IfIcmpeq { target }
53                | JvmInstruction::IfIcmpne { target }
54                | JvmInstruction::IfIcmplt { target }
55                | JvmInstruction::IfIcmpge { target }
56                | JvmInstruction::IfIcmpgt { target }
57                | JvmInstruction::IfIcmple { target }
58                | JvmInstruction::IfAcmpeq { target }
59                | JvmInstruction::IfAcmpne { target }
60                | JvmInstruction::Ifnull { target }
61                | JvmInstruction::Ifnonnull { target }
62                | JvmInstruction::Goto { target }
63                | JvmInstruction::GotoW { target } => {
64                    if let Some(&pos) = self.label_positions.get(target) {
65                        targets.insert(pos);
66                    }
67                }
68                JvmInstruction::Tableswitch { default, targets: switch_targets, .. } => {
69                    if let Some(&pos) = self.label_positions.get(default) {
70                        targets.insert(pos);
71                    }
72                    for target in switch_targets {
73                        if let Some(&pos) = self.label_positions.get(target) {
74                            targets.insert(pos);
75                        }
76                    }
77                }
78                JvmInstruction::Lookupswitch { default, pairs, .. } => {
79                    if let Some(&pos) = self.label_positions.get(default) {
80                        targets.insert(pos);
81                    }
82                    for (_, target) in pairs {
83                        if let Some(&pos) = self.label_positions.get(target) {
84                            targets.insert(pos);
85                        }
86                    }
87                }
88                _ => {}
89            }
90        }
91
92        // 异常处理器也是跳转目标
93        for handler in &self.method.exception_handlers {
94            if let Some(&pos) = self.label_positions.get(&handler.handler_label) {
95                targets.insert(pos);
96            }
97        }
98
99        targets
100    }
101
102    /// 生成一个 Full 帧(目前作为通用方案)
103    fn generate_full_frame(&self, offset_delta: u16) -> JvmStackMapFrame {
104        // TODO: 真正实现局部变量和操作数栈的状态追踪
105        // 目前返回一个空的 locals 和 stack,这通常不正确,但展示了框架结构
106        JvmStackMapFrame::Full { offset_delta, locals: Vec::new(), stack: Vec::new() }
107    }
108}