1use crate::opcodes;
2
3#[derive(Debug, Clone)]
4pub struct InsnNode {
5 pub opcode: u8,
6}
7
8#[derive(Debug, Clone)]
9pub struct IntInsnNode {
10 pub insn: InsnNode,
11 pub operand: i32,
12}
13
14#[derive(Debug, Clone)]
15pub struct VarInsnNode {
16 pub insn: InsnNode,
17 pub var_index: u16,
18}
19
20#[derive(Debug, Clone)]
21pub struct TypeInsnNode {
22 pub insn: InsnNode,
23 pub type_index: u16,
24}
25
26#[derive(Debug, Clone)]
27pub struct FieldInsnNode {
28 pub insn: InsnNode,
29 pub field_ref: MemberRef,
30}
31
32#[derive(Debug, Clone)]
33pub struct MethodInsnNode {
34 pub insn: InsnNode,
35 pub method_ref: MemberRef,
36}
37
38#[derive(Debug, Clone)]
39pub struct InvokeInterfaceInsnNode {
40 pub insn: InsnNode,
41 pub method_index: u16,
42 pub count: u8,
43}
44
45#[derive(Debug, Clone)]
46pub struct InvokeDynamicInsnNode {
47 pub insn: InsnNode,
48 pub method_index: u16,
49}
50
51#[derive(Debug, Clone)]
52pub struct JumpInsnNode {
53 pub insn: InsnNode,
54 pub offset: i32,
55}
56
57#[derive(Debug, Clone)]
58pub struct LdcInsnNode {
59 pub insn: InsnNode,
60 pub value: LdcValue,
61}
62
63#[derive(Debug, Clone)]
64pub struct IincInsnNode {
65 pub insn: InsnNode,
66 pub var_index: u16,
67 pub increment: i16,
68}
69
70#[derive(Debug, Clone)]
71pub struct TableSwitchInsnNode {
72 pub insn: InsnNode,
73 pub default_offset: i32,
74 pub low: i32,
75 pub high: i32,
76 pub offsets: Vec<i32>,
77}
78
79#[derive(Debug, Clone)]
80pub struct LookupSwitchInsnNode {
81 pub insn: InsnNode,
82 pub default_offset: i32,
83 pub pairs: Vec<(i32, i32)>,
84}
85
86#[derive(Debug, Clone)]
87pub struct MultiANewArrayInsnNode {
88 pub insn: InsnNode,
89 pub type_index: u16,
90 pub dimensions: u8,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
94pub struct LabelNode {
95 pub id: usize,
96}
97
98#[derive(Debug, Clone)]
99pub struct TryCatchBlockNode {
100 pub start: LabelNode,
101 pub end: LabelNode,
102 pub handler: LabelNode,
103 pub catch_type: Option<String>,
104}
105
106#[derive(Debug, Clone)]
107pub enum AbstractInsnNode {
108 Label(LabelNode),
109 Insn(Insn),
110}
111
112#[derive(Debug, Clone)]
113pub enum Insn {
114 Simple(InsnNode),
115 Int(IntInsnNode),
116 Var(VarInsnNode),
117 Type(TypeInsnNode),
118 Field(FieldInsnNode),
119 Method(MethodInsnNode),
120 InvokeInterface(InvokeInterfaceInsnNode),
121 InvokeDynamic(InvokeDynamicInsnNode),
122 Jump(JumpInsnNode),
123 Ldc(LdcInsnNode),
124 Iinc(IincInsnNode),
125 TableSwitch(TableSwitchInsnNode),
126 LookupSwitch(LookupSwitchInsnNode),
127 MultiANewArray(MultiANewArrayInsnNode),
128}
129
130#[derive(Debug, Clone)]
131pub enum MemberRef {
132 Index(u16),
133 Symbolic {
134 owner: String,
135 name: String,
136 descriptor: String,
137 },
138}
139
140#[derive(Debug, Clone)]
141pub enum LdcValue {
142 Index(u16),
143 String(String),
144}
145
146#[derive(Debug, Clone, Default)]
147pub struct InsnList {
148 insns: Vec<Insn>,
149}
150
151impl InsnList {
152 pub fn new() -> Self {
153 Self { insns: Vec::new() }
154 }
155
156 pub fn add<T: Into<Insn>>(&mut self, insn: T) -> &mut Self {
157 self.insns.push(insn.into());
158 self
159 }
160
161 pub fn insns(&self) -> &[Insn] {
162 &self.insns
163 }
164
165 pub fn into_insns(self) -> Vec<Insn> {
166 self.insns
167 }
168}
169
170#[derive(Debug, Clone, Default)]
171pub struct NodeList {
172 nodes: Vec<AbstractInsnNode>,
173}
174
175impl NodeList {
176 pub fn new() -> Self {
177 Self { nodes: Vec::new() }
178 }
179
180 pub fn add<T: Into<AbstractInsnNode>>(&mut self, node: T) -> &mut Self {
181 self.nodes.push(node.into());
182 self
183 }
184
185 pub fn nodes(&self) -> &[AbstractInsnNode] {
186 &self.nodes
187 }
188
189 pub fn into_nodes(self) -> Vec<AbstractInsnNode> {
190 self.nodes
191 }
192}
193
194impl From<LabelNode> for AbstractInsnNode {
195 fn from(value: LabelNode) -> Self {
196 AbstractInsnNode::Label(value)
197 }
198}
199
200impl From<Insn> for AbstractInsnNode {
201 fn from(value: Insn) -> Self {
202 AbstractInsnNode::Insn(value)
203 }
204}
205
206impl FieldInsnNode {
207 pub fn new(opcode: u8, owner: &str, name: &str, descriptor: &str) -> Self {
208 Self {
209 insn: InsnNode { opcode },
210 field_ref: MemberRef::Symbolic {
211 owner: owner.to_string(),
212 name: name.to_string(),
213 descriptor: descriptor.to_string(),
214 },
215 }
216 }
217
218 pub fn from_index(opcode: u8, index: u16) -> Self {
219 Self {
220 insn: InsnNode { opcode },
221 field_ref: MemberRef::Index(index),
222 }
223 }
224}
225
226impl MethodInsnNode {
227 pub fn new(opcode: u8, owner: &str, name: &str, descriptor: &str) -> Self {
228 Self {
229 insn: InsnNode { opcode },
230 method_ref: MemberRef::Symbolic {
231 owner: owner.to_string(),
232 name: name.to_string(),
233 descriptor: descriptor.to_string(),
234 },
235 }
236 }
237
238 pub fn from_index(opcode: u8, index: u16) -> Self {
239 Self {
240 insn: InsnNode { opcode },
241 method_ref: MemberRef::Index(index),
242 }
243 }
244}
245
246impl LdcInsnNode {
247 pub fn from_index(opcode: u8, index: u16) -> Self {
248 Self {
249 insn: InsnNode { opcode },
250 value: LdcValue::Index(index),
251 }
252 }
253
254 pub fn string(value: &str) -> Self {
255 Self {
256 insn: InsnNode {
257 opcode: opcodes::LDC,
258 },
259 value: LdcValue::String(value.to_string()),
260 }
261 }
262}
263
264impl From<InsnNode> for Insn {
265 fn from(value: InsnNode) -> Self {
266 Insn::Simple(value)
267 }
268}
269
270impl From<IntInsnNode> for Insn {
271 fn from(value: IntInsnNode) -> Self {
272 Insn::Int(value)
273 }
274}
275
276impl From<VarInsnNode> for Insn {
277 fn from(value: VarInsnNode) -> Self {
278 Insn::Var(value)
279 }
280}
281
282impl From<TypeInsnNode> for Insn {
283 fn from(value: TypeInsnNode) -> Self {
284 Insn::Type(value)
285 }
286}
287
288impl From<FieldInsnNode> for Insn {
289 fn from(value: FieldInsnNode) -> Self {
290 Insn::Field(value)
291 }
292}
293
294impl From<MethodInsnNode> for Insn {
295 fn from(value: MethodInsnNode) -> Self {
296 Insn::Method(value)
297 }
298}
299
300impl From<InvokeInterfaceInsnNode> for Insn {
301 fn from(value: InvokeInterfaceInsnNode) -> Self {
302 Insn::InvokeInterface(value)
303 }
304}
305
306impl From<InvokeDynamicInsnNode> for Insn {
307 fn from(value: InvokeDynamicInsnNode) -> Self {
308 Insn::InvokeDynamic(value)
309 }
310}
311
312impl From<JumpInsnNode> for Insn {
313 fn from(value: JumpInsnNode) -> Self {
314 Insn::Jump(value)
315 }
316}
317
318impl From<LdcInsnNode> for Insn {
319 fn from(value: LdcInsnNode) -> Self {
320 Insn::Ldc(value)
321 }
322}
323
324impl From<IincInsnNode> for Insn {
325 fn from(value: IincInsnNode) -> Self {
326 Insn::Iinc(value)
327 }
328}
329
330impl From<TableSwitchInsnNode> for Insn {
331 fn from(value: TableSwitchInsnNode) -> Self {
332 Insn::TableSwitch(value)
333 }
334}
335
336impl From<LookupSwitchInsnNode> for Insn {
337 fn from(value: LookupSwitchInsnNode) -> Self {
338 Insn::LookupSwitch(value)
339 }
340}
341
342impl From<MultiANewArrayInsnNode> for Insn {
343 fn from(value: MultiANewArrayInsnNode) -> Self {
344 Insn::MultiANewArray(value)
345 }
346}