Skip to main content

jvm_assembler/formats/class/writer/
instructions.rs

1use super::ClassWriter;
2use crate::{formats::class::writer::utils::calculate_parameter_count, program::*};
3use std::io::Write;
4
5impl<W: Write> ClassWriter<W> {
6    /// 生成方法的字节码及标签位置
7    pub fn generate_method_bytecode(&mut self, method: &JvmMethod) -> (Vec<u8>, std::collections::HashMap<String, i32>) {
8        let mut bytecode = Vec::new();
9        let mut label_positions = std::collections::HashMap::new();
10        let mut jump_patches = Vec::new(); // (instr_pos, patch_pos, target_label_name, is_wide)
11
12        // 第一遍:计算指令位置并记录标签位置
13        for instruction in &method.instructions {
14            match instruction {
15                JvmInstruction::Label { name } => {
16                    label_positions.insert(name.clone(), bytecode.len() as i32);
17                }
18                _ => {
19                    let pos = bytecode.len();
20                    self.emit_instruction(instruction, &mut bytecode, &mut jump_patches, pos);
21                }
22            }
23        }
24
25        // 第二遍:解析跳转偏移量
26        for (instr_pos, patch_pos, target_name, is_wide) in jump_patches {
27            if let Some(&target_pos) = label_positions.get(&target_name) {
28                let offset = target_pos - instr_pos as i32;
29                if is_wide {
30                    // 4 字节偏移量
31                    bytecode[patch_pos] = ((offset >> 24) & 0xFF) as u8;
32                    bytecode[patch_pos + 1] = ((offset >> 16) & 0xFF) as u8;
33                    bytecode[patch_pos + 2] = ((offset >> 8) & 0xFF) as u8;
34                    bytecode[patch_pos + 3] = (offset & 0xFF) as u8;
35                }
36                else {
37                    // 2 字节偏移量
38                    bytecode[patch_pos] = ((offset >> 8) & 0xFF) as u8;
39                    bytecode[patch_pos + 1] = (offset & 0xFF) as u8;
40                }
41            }
42        }
43
44        // 如果方法没有指令,添加一个 return 指令
45        if bytecode.is_empty() {
46            bytecode.push(0xB1); // return
47        }
48
49        (bytecode, label_positions)
50    }
51
52    /// 发射单条指令的字节码
53    pub fn emit_instruction(
54        &mut self,
55        instruction: &JvmInstruction,
56        bytecode: &mut Vec<u8>,
57        jump_patches: &mut Vec<(usize, usize, String, bool)>,
58        pos: usize,
59    ) {
60        match instruction {
61            JvmInstruction::Nop => bytecode.push(0x00),
62            JvmInstruction::AconstNull => bytecode.push(0x01),
63            JvmInstruction::IconstM1 => bytecode.push(0x02),
64            JvmInstruction::Iconst0 => bytecode.push(0x03),
65            JvmInstruction::Iconst1 => bytecode.push(0x04),
66            JvmInstruction::Iconst2 => bytecode.push(0x05),
67            JvmInstruction::Iconst3 => bytecode.push(0x06),
68            JvmInstruction::Iconst4 => bytecode.push(0x07),
69            JvmInstruction::Iconst5 => bytecode.push(0x08),
70            JvmInstruction::Lconst0 => bytecode.push(0x09),
71            JvmInstruction::Lconst1 => bytecode.push(0x0A),
72            JvmInstruction::Fconst0 => bytecode.push(0x0B),
73            JvmInstruction::Fconst1 => bytecode.push(0x0C),
74            JvmInstruction::Fconst2 => bytecode.push(0x0D),
75            JvmInstruction::Dconst0 => bytecode.push(0x0E),
76            JvmInstruction::Dconst1 => bytecode.push(0x0F),
77
78            JvmInstruction::Bipush { value } => {
79                bytecode.push(0x10);
80                bytecode.push(*value as u8);
81            }
82            JvmInstruction::Sipush { value } => {
83                bytecode.push(0x11);
84                bytecode.push((*value >> 8) as u8);
85                bytecode.push((*value & 0xFF) as u8);
86            }
87
88            JvmInstruction::Ldc { symbol } => {
89                let index = self.add_string(symbol.clone());
90                if index < 256 {
91                    bytecode.push(0x12); // ldc
92                    bytecode.push(index as u8);
93                }
94                else {
95                    bytecode.push(0x13); // ldc_w
96                    bytecode.push((index >> 8) as u8);
97                    bytecode.push((index & 0xFF) as u8);
98                }
99            }
100            JvmInstruction::LdcW { symbol } => {
101                let index = self.add_string(symbol.clone());
102                bytecode.push(0x13); // ldc_w
103                bytecode.push((index >> 8) as u8);
104                bytecode.push((index & 0xFF) as u8);
105            }
106            JvmInstruction::Ldc2W { symbol } => {
107                // 尝试解析为长整型
108                if let Ok(long_val) = symbol.parse::<i64>() {
109                    let index = self.add_long(long_val);
110                    bytecode.push(0x14); // ldc2_w
111                    bytecode.push((index >> 8) as u8);
112                    bytecode.push((index & 0xFF) as u8);
113                }
114                // 尝试解析为双精度浮点型
115                else if let Ok(double_val) = symbol.parse::<f64>() {
116                    let index = self.add_double(double_val);
117                    bytecode.push(0x14); // ldc2_w
118                    bytecode.push((index >> 8) as u8);
119                    bytecode.push((index & 0xFF) as u8);
120                }
121                // 作为字符串处理
122                else {
123                    let index = self.add_string(symbol.clone());
124                    bytecode.push(0x14); // ldc2_w
125                    bytecode.push((index >> 8) as u8);
126                    bytecode.push((index & 0xFF) as u8);
127                }
128            }
129
130            JvmInstruction::Iload { index } => {
131                if *index <= 3 {
132                    bytecode.push(0x1A + *index as u8);
133                }
134                else if *index <= 255 {
135                    bytecode.push(0x15);
136                    bytecode.push(*index as u8);
137                }
138                else {
139                    bytecode.push(0xC4); // wide
140                    bytecode.push(0x15);
141                    bytecode.push((*index >> 8) as u8);
142                    bytecode.push((*index & 0xFF) as u8);
143                }
144            }
145            JvmInstruction::Iload0 => bytecode.push(0x1A),
146            JvmInstruction::Iload1 => bytecode.push(0x1B),
147            JvmInstruction::Iload2 => bytecode.push(0x1C),
148            JvmInstruction::Iload3 => bytecode.push(0x1D),
149
150            JvmInstruction::Lload { index } => {
151                if *index <= 3 {
152                    bytecode.push(0x1E + *index as u8);
153                }
154                else if *index <= 255 {
155                    bytecode.push(0x16);
156                    bytecode.push(*index as u8);
157                }
158                else {
159                    bytecode.push(0xC4); // wide
160                    bytecode.push(0x16);
161                    bytecode.push((*index >> 8) as u8);
162                    bytecode.push((*index & 0xFF) as u8);
163                }
164            }
165            JvmInstruction::Lload0 => bytecode.push(0x1E),
166            JvmInstruction::Lload1 => bytecode.push(0x1F),
167            JvmInstruction::Lload2 => bytecode.push(0x20),
168            JvmInstruction::Lload3 => bytecode.push(0x21),
169
170            JvmInstruction::Fload { index } => {
171                if *index <= 3 {
172                    bytecode.push(0x22 + *index as u8);
173                }
174                else if *index <= 255 {
175                    bytecode.push(0x17);
176                    bytecode.push(*index as u8);
177                }
178                else {
179                    bytecode.push(0xC4); // wide
180                    bytecode.push(0x17);
181                    bytecode.push((*index >> 8) as u8);
182                    bytecode.push((*index & 0xFF) as u8);
183                }
184            }
185            JvmInstruction::Fload0 => bytecode.push(0x22),
186            JvmInstruction::Fload1 => bytecode.push(0x23),
187            JvmInstruction::Fload2 => bytecode.push(0x24),
188            JvmInstruction::Fload3 => bytecode.push(0x25),
189
190            JvmInstruction::Dload { index } => {
191                if *index <= 3 {
192                    bytecode.push(0x26 + *index as u8);
193                }
194                else if *index <= 255 {
195                    bytecode.push(0x18);
196                    bytecode.push(*index as u8);
197                }
198                else {
199                    bytecode.push(0xC4); // wide
200                    bytecode.push(0x18);
201                    bytecode.push((*index >> 8) as u8);
202                    bytecode.push((*index & 0xFF) as u8);
203                }
204            }
205            JvmInstruction::Dload0 => bytecode.push(0x26),
206            JvmInstruction::Dload1 => bytecode.push(0x27),
207            JvmInstruction::Dload2 => bytecode.push(0x28),
208            JvmInstruction::Dload3 => bytecode.push(0x29),
209
210            JvmInstruction::Aload { index } => {
211                if *index <= 3 {
212                    bytecode.push(0x2A + *index as u8);
213                }
214                else if *index <= 255 {
215                    bytecode.push(0x19);
216                    bytecode.push(*index as u8);
217                }
218                else {
219                    bytecode.push(0xC4); // wide
220                    bytecode.push(0x19);
221                    bytecode.push((*index >> 8) as u8);
222                    bytecode.push((*index & 0xFF) as u8);
223                }
224            }
225            JvmInstruction::Aload0 => bytecode.push(0x2A),
226            JvmInstruction::Aload1 => bytecode.push(0x2B),
227            JvmInstruction::Aload2 => bytecode.push(0x2C),
228            JvmInstruction::Aload3 => bytecode.push(0x2D),
229
230            JvmInstruction::Istore { index } => {
231                if *index <= 3 {
232                    bytecode.push(0x3B + *index as u8);
233                }
234                else if *index <= 255 {
235                    bytecode.push(0x36);
236                    bytecode.push(*index as u8);
237                }
238                else {
239                    bytecode.push(0xC4); // wide
240                    bytecode.push(0x36);
241                    bytecode.push((*index >> 8) as u8);
242                    bytecode.push((*index & 0xFF) as u8);
243                }
244            }
245            JvmInstruction::Istore0 => bytecode.push(0x3B),
246            JvmInstruction::Istore1 => bytecode.push(0x3C),
247            JvmInstruction::Istore2 => bytecode.push(0x3D),
248            JvmInstruction::Istore3 => bytecode.push(0x3E),
249
250            JvmInstruction::Lstore { index } => {
251                if *index <= 3 {
252                    bytecode.push(0x3F + *index as u8);
253                }
254                else if *index <= 255 {
255                    bytecode.push(0x37);
256                    bytecode.push(*index as u8);
257                }
258                else {
259                    bytecode.push(0xC4); // wide
260                    bytecode.push(0x37);
261                    bytecode.push((*index >> 8) as u8);
262                    bytecode.push((*index & 0xFF) as u8);
263                }
264            }
265            JvmInstruction::Lstore0 => bytecode.push(0x3F),
266            JvmInstruction::Lstore1 => bytecode.push(0x40),
267            JvmInstruction::Lstore2 => bytecode.push(0x41),
268            JvmInstruction::Lstore3 => bytecode.push(0x42),
269
270            JvmInstruction::Fstore { index } => {
271                if *index <= 3 {
272                    bytecode.push(0x43 + *index as u8);
273                }
274                else if *index <= 255 {
275                    bytecode.push(0x38);
276                    bytecode.push(*index as u8);
277                }
278                else {
279                    bytecode.push(0xC4); // wide
280                    bytecode.push(0x38);
281                    bytecode.push((*index >> 8) as u8);
282                    bytecode.push((*index & 0xFF) as u8);
283                }
284            }
285            JvmInstruction::Fstore0 => bytecode.push(0x43),
286            JvmInstruction::Fstore1 => bytecode.push(0x44),
287            JvmInstruction::Fstore2 => bytecode.push(0x45),
288            JvmInstruction::Fstore3 => bytecode.push(0x46),
289
290            JvmInstruction::Dstore { index } => {
291                if *index <= 3 {
292                    bytecode.push(0x47 + *index as u8);
293                }
294                else if *index <= 255 {
295                    bytecode.push(0x39);
296                    bytecode.push(*index as u8);
297                }
298                else {
299                    bytecode.push(0xC4); // wide
300                    bytecode.push(0x39);
301                    bytecode.push((*index >> 8) as u8);
302                    bytecode.push((*index & 0xFF) as u8);
303                }
304            }
305            JvmInstruction::Dstore0 => bytecode.push(0x47),
306            JvmInstruction::Dstore1 => bytecode.push(0x48),
307            JvmInstruction::Dstore2 => bytecode.push(0x49),
308            JvmInstruction::Dstore3 => bytecode.push(0x4A),
309
310            JvmInstruction::Astore { index } => {
311                if *index <= 3 {
312                    bytecode.push(0x4B + *index as u8);
313                }
314                else if *index <= 255 {
315                    bytecode.push(0x3A);
316                    bytecode.push(*index as u8);
317                }
318                else {
319                    bytecode.push(0xC4); // wide
320                    bytecode.push(0x3A);
321                    bytecode.push((*index >> 8) as u8);
322                    bytecode.push((*index & 0xFF) as u8);
323                }
324            }
325            JvmInstruction::Astore0 => bytecode.push(0x4B),
326            JvmInstruction::Astore1 => bytecode.push(0x4C),
327            JvmInstruction::Astore2 => bytecode.push(0x4D),
328            JvmInstruction::Astore3 => bytecode.push(0x4E),
329
330            JvmInstruction::Pop => bytecode.push(0x57),
331            JvmInstruction::Pop2 => bytecode.push(0x58),
332            JvmInstruction::Dup => bytecode.push(0x59),
333            JvmInstruction::DupX1 => bytecode.push(0x5A),
334            JvmInstruction::DupX2 => bytecode.push(0x5B),
335            JvmInstruction::Dup2 => bytecode.push(0x5C),
336            JvmInstruction::Dup2X1 => bytecode.push(0x5D),
337            JvmInstruction::Dup2X2 => bytecode.push(0x5E),
338            JvmInstruction::Swap => bytecode.push(0x5F),
339
340            JvmInstruction::Iadd => bytecode.push(0x60),
341            JvmInstruction::Ladd => bytecode.push(0x61),
342            JvmInstruction::Fadd => bytecode.push(0x62),
343            JvmInstruction::Dadd => bytecode.push(0x63),
344            JvmInstruction::Isub => bytecode.push(0x64),
345            JvmInstruction::Lsub => bytecode.push(0x65),
346            JvmInstruction::Fsub => bytecode.push(0x66),
347            JvmInstruction::Dsub => bytecode.push(0x67),
348            JvmInstruction::Imul => bytecode.push(0x68),
349            JvmInstruction::Lmul => bytecode.push(0x69),
350            JvmInstruction::Fmul => bytecode.push(0x6A),
351            JvmInstruction::Dmul => bytecode.push(0x6B),
352            JvmInstruction::Idiv => bytecode.push(0x6C),
353            JvmInstruction::Ldiv => bytecode.push(0x6D),
354            JvmInstruction::Fdiv => bytecode.push(0x6E),
355            JvmInstruction::Ddiv => bytecode.push(0x6F),
356            JvmInstruction::Irem => bytecode.push(0x70),
357            JvmInstruction::Lrem => bytecode.push(0x71),
358            JvmInstruction::Frem => bytecode.push(0x72),
359            JvmInstruction::Drem => bytecode.push(0x73),
360            JvmInstruction::Ineg => bytecode.push(0x74),
361            JvmInstruction::Lneg => bytecode.push(0x75),
362            JvmInstruction::Fneg => bytecode.push(0x76),
363            JvmInstruction::Dneg => bytecode.push(0x77),
364
365            JvmInstruction::Ishl => bytecode.push(0x78),
366            JvmInstruction::Lshl => bytecode.push(0x79),
367            JvmInstruction::Ishr => bytecode.push(0x7A),
368            JvmInstruction::Lshr => bytecode.push(0x7B),
369            JvmInstruction::Iushr => bytecode.push(0x7C),
370            JvmInstruction::Lushr => bytecode.push(0x7D),
371            JvmInstruction::Iand => bytecode.push(0x7E),
372            JvmInstruction::Land => bytecode.push(0x7F),
373            JvmInstruction::Ior => bytecode.push(0x80),
374            JvmInstruction::Lor => bytecode.push(0x81),
375            JvmInstruction::Ixor => bytecode.push(0x82),
376            JvmInstruction::Lxor => bytecode.push(0x83),
377
378            JvmInstruction::Lcmp => bytecode.push(0x94),
379            JvmInstruction::Fcmpl => bytecode.push(0x95),
380            JvmInstruction::Fcmpg => bytecode.push(0x96),
381            JvmInstruction::Dcmpl => bytecode.push(0x97),
382            JvmInstruction::Dcmpg => bytecode.push(0x98),
383
384            JvmInstruction::Ifeq { target } => {
385                jump_patches.push((pos, pos + 1, target.clone(), false));
386                bytecode.push(0x99);
387                bytecode.push(0);
388                bytecode.push(0);
389            }
390            JvmInstruction::Ifne { target } => {
391                jump_patches.push((pos, pos + 1, target.clone(), false));
392                bytecode.push(0x9A);
393                bytecode.push(0);
394                bytecode.push(0);
395            }
396            JvmInstruction::Iflt { target } => {
397                jump_patches.push((pos, pos + 1, target.clone(), false));
398                bytecode.push(0x9B);
399                bytecode.push(0);
400                bytecode.push(0);
401            }
402            JvmInstruction::Ifge { target } => {
403                jump_patches.push((pos, pos + 1, target.clone(), false));
404                bytecode.push(0x9C);
405                bytecode.push(0);
406                bytecode.push(0);
407            }
408            JvmInstruction::Ifgt { target } => {
409                jump_patches.push((pos, pos + 1, target.clone(), false));
410                bytecode.push(0x9D);
411                bytecode.push(0);
412                bytecode.push(0);
413            }
414            JvmInstruction::Ifle { target } => {
415                jump_patches.push((pos, pos + 1, target.clone(), false));
416                bytecode.push(0x9E);
417                bytecode.push(0);
418                bytecode.push(0);
419            }
420            JvmInstruction::IfIcmpeq { target } => {
421                jump_patches.push((pos, pos + 1, target.clone(), false));
422                bytecode.push(0x9F);
423                bytecode.push(0);
424                bytecode.push(0);
425            }
426            JvmInstruction::IfIcmpne { target } => {
427                jump_patches.push((pos, pos + 1, target.clone(), false));
428                bytecode.push(0xA0);
429                bytecode.push(0);
430                bytecode.push(0);
431            }
432            JvmInstruction::IfIcmplt { target } => {
433                jump_patches.push((pos, pos + 1, target.clone(), false));
434                bytecode.push(0xA1);
435                bytecode.push(0);
436                bytecode.push(0);
437            }
438            JvmInstruction::IfIcmpge { target } => {
439                jump_patches.push((pos, pos + 1, target.clone(), false));
440                bytecode.push(0xA2);
441                bytecode.push(0);
442                bytecode.push(0);
443            }
444            JvmInstruction::IfIcmpgt { target } => {
445                jump_patches.push((pos, pos + 1, target.clone(), false));
446                bytecode.push(0xA3);
447                bytecode.push(0);
448                bytecode.push(0);
449            }
450            JvmInstruction::IfIcmple { target } => {
451                jump_patches.push((pos, pos + 1, target.clone(), false));
452                bytecode.push(0xA4);
453                bytecode.push(0);
454                bytecode.push(0);
455            }
456            JvmInstruction::IfAcmpeq { target } => {
457                jump_patches.push((pos, pos + 1, target.clone(), false));
458                bytecode.push(0xA5);
459                bytecode.push(0);
460                bytecode.push(0);
461            }
462            JvmInstruction::IfAcmpne { target } => {
463                jump_patches.push((pos, pos + 1, target.clone(), false));
464                bytecode.push(0xA6);
465                bytecode.push(0);
466                bytecode.push(0);
467            }
468            JvmInstruction::Ifnull { target } => {
469                jump_patches.push((pos, pos + 1, target.clone(), false));
470                bytecode.push(0xC6);
471                bytecode.push(0);
472                bytecode.push(0);
473            }
474            JvmInstruction::Ifnonnull { target } => {
475                jump_patches.push((pos, pos + 1, target.clone(), false));
476                bytecode.push(0xC7);
477                bytecode.push(0);
478                bytecode.push(0);
479            }
480            JvmInstruction::Goto { target } => {
481                jump_patches.push((pos, pos + 1, target.clone(), false));
482                bytecode.push(0xA7);
483                bytecode.push(0);
484                bytecode.push(0);
485            }
486            JvmInstruction::GotoW { target } => {
487                jump_patches.push((pos, pos + 1, target.clone(), true));
488                bytecode.push(0xC8);
489                bytecode.push(0);
490                bytecode.push(0);
491                bytecode.push(0);
492                bytecode.push(0);
493            }
494
495            JvmInstruction::Return => bytecode.push(0xB1),
496            JvmInstruction::Ireturn => bytecode.push(0xAC),
497            JvmInstruction::Lreturn => bytecode.push(0xAD),
498            JvmInstruction::Freturn => bytecode.push(0xAE),
499            JvmInstruction::Dreturn => bytecode.push(0xAF),
500            JvmInstruction::Areturn => bytecode.push(0xB0),
501
502            JvmInstruction::Arraylength => bytecode.push(0xBE),
503            JvmInstruction::Athrow => bytecode.push(0xBF),
504            JvmInstruction::Monitorenter => bytecode.push(0xC2),
505            JvmInstruction::Monitorexit => bytecode.push(0xC3),
506
507            JvmInstruction::Iaload => bytecode.push(0x2E),
508            JvmInstruction::Laload => bytecode.push(0x2F),
509            JvmInstruction::Faload => bytecode.push(0x30),
510            JvmInstruction::Daload => bytecode.push(0x31),
511            JvmInstruction::Aaload => bytecode.push(0x32),
512            JvmInstruction::Baload => bytecode.push(0x33),
513            JvmInstruction::Saload => bytecode.push(0x34),
514            JvmInstruction::Caload => bytecode.push(0x35),
515
516            JvmInstruction::Iastore => bytecode.push(0x4F),
517            JvmInstruction::Lastore => bytecode.push(0x50),
518            JvmInstruction::Fastore => bytecode.push(0x51),
519            JvmInstruction::Dastore => bytecode.push(0x52),
520            JvmInstruction::Aastore => bytecode.push(0x53),
521            JvmInstruction::Bastore => bytecode.push(0x54),
522            JvmInstruction::Sastore => bytecode.push(0x55),
523            JvmInstruction::Castore => bytecode.push(0x56),
524
525            JvmInstruction::Getstatic { class_name, field_name, descriptor } => {
526                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
527                bytecode.push(0xB2); // getstatic
528                bytecode.push((index >> 8) as u8);
529                bytecode.push((index & 0xFF) as u8);
530            }
531            JvmInstruction::Putstatic { class_name, field_name, descriptor } => {
532                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
533                bytecode.push(0xB3); // putstatic
534                bytecode.push((index >> 8) as u8);
535                bytecode.push((index & 0xFF) as u8);
536            }
537            JvmInstruction::Getfield { class_name, field_name, descriptor } => {
538                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
539                bytecode.push(0xB4); // getfield
540                bytecode.push((index >> 8) as u8);
541                bytecode.push((index & 0xFF) as u8);
542            }
543            JvmInstruction::Putfield { class_name, field_name, descriptor } => {
544                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
545                bytecode.push(0xB5); // putfield
546                bytecode.push((index >> 8) as u8);
547                bytecode.push((index & 0xFF) as u8);
548            }
549            JvmInstruction::Invokevirtual { class_name, method_name, descriptor } => {
550                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
551                bytecode.push(0xB6); // invokevirtual
552                bytecode.push((index >> 8) as u8);
553                bytecode.push((index & 0xFF) as u8);
554            }
555            JvmInstruction::Invokespecial { class_name, method_name, descriptor } => {
556                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
557                bytecode.push(0xB7); // invokespecial
558                bytecode.push((index >> 8) as u8);
559                bytecode.push((index & 0xFF) as u8);
560            }
561            JvmInstruction::Invokestatic { class_name, method_name, descriptor } => {
562                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
563                bytecode.push(0xB8); // invokestatic
564                bytecode.push((index >> 8) as u8);
565                bytecode.push((index & 0xFF) as u8);
566            }
567            JvmInstruction::Invokeinterface { class_name, method_name, descriptor } => {
568                let index = self.add_interface_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
569                bytecode.push(0xB9); // invokeinterface
570                bytecode.push((index >> 8) as u8);
571                bytecode.push((index & 0xFF) as u8);
572
573                // 计算参数数量(包括 this)
574                let count = calculate_parameter_count(descriptor) + 1;
575                bytecode.push(count as u8);
576                bytecode.push(0);
577            }
578            JvmInstruction::Invokedynamic { class_name, method_name, descriptor } => {
579                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
580                bytecode.push(0xBA); // invokedynamic
581                bytecode.push((index >> 8) as u8);
582                bytecode.push((index & 0xFF) as u8);
583                bytecode.push(0);
584                bytecode.push(0);
585            }
586            JvmInstruction::New { class_name } => {
587                let index = self.add_class(class_name.clone());
588                bytecode.push(0xBB); // new
589                bytecode.push((index >> 8) as u8);
590                bytecode.push((index & 0xFF) as u8);
591            }
592            JvmInstruction::Newarray { type_code } => {
593                bytecode.push(0xBC); // newarray
594                bytecode.push(*type_code);
595            }
596            JvmInstruction::Anewarray { class_name } => {
597                let index = self.add_class(class_name.clone());
598                bytecode.push(0xBD); // anewarray
599                bytecode.push((index >> 8) as u8);
600                bytecode.push((index & 0xFF) as u8);
601            }
602            JvmInstruction::Multianewarray { class_name, dimensions } => {
603                let index = self.add_class(class_name.clone());
604                bytecode.push(0xC5); // multianewarray
605                bytecode.push((index >> 8) as u8);
606                bytecode.push((index & 0xFF) as u8);
607                bytecode.push(*dimensions);
608            }
609            JvmInstruction::Checkcast { class_name } => {
610                let index = self.add_class(class_name.clone());
611                bytecode.push(0xC0); // checkcast
612                bytecode.push((index >> 8) as u8);
613                bytecode.push((index & 0xFF) as u8);
614            }
615            JvmInstruction::Instanceof { class_name } => {
616                let index = self.add_class(class_name.clone());
617                bytecode.push(0xC1); // instanceof
618                bytecode.push((index >> 8) as u8);
619                bytecode.push((index & 0xFF) as u8);
620            }
621            JvmInstruction::Jsr { target } => {
622                jump_patches.push((pos, pos + 1, target.clone(), false));
623                bytecode.push(0xA8); // jsr
624                bytecode.push(0);
625                bytecode.push(0);
626            }
627            JvmInstruction::Ret { index } => {
628                if *index <= 255 {
629                    bytecode.push(0xA9); // ret
630                    bytecode.push(*index as u8);
631                }
632                else {
633                    bytecode.push(0xC4); // wide
634                    bytecode.push(0xA9);
635                    bytecode.push((*index >> 8) as u8);
636                    bytecode.push((*index & 0xFF) as u8);
637                }
638            }
639            JvmInstruction::Iinc { index, value } => {
640                if *index <= 255 && *value >= -128 && *value <= 127 {
641                    bytecode.push(0x84); // iinc
642                    bytecode.push(*index as u8);
643                    bytecode.push(*value as u8);
644                }
645                else {
646                    bytecode.push(0xC4); // wide
647                    bytecode.push(0x84);
648                    bytecode.push((*index >> 8) as u8);
649                    bytecode.push((*index & 0xFF) as u8);
650                    bytecode.push((*value >> 8) as u8);
651                    bytecode.push((*value & 0xFF) as u8);
652                }
653            }
654
655            JvmInstruction::I2l => bytecode.push(0x85),
656            JvmInstruction::I2f => bytecode.push(0x86),
657            JvmInstruction::I2d => bytecode.push(0x87),
658            JvmInstruction::L2i => bytecode.push(0x88),
659            JvmInstruction::L2f => bytecode.push(0x89),
660            JvmInstruction::L2d => bytecode.push(0x8A),
661            JvmInstruction::F2i => bytecode.push(0x8B),
662            JvmInstruction::F2l => bytecode.push(0x8C),
663            JvmInstruction::F2d => bytecode.push(0x8D),
664            JvmInstruction::D2i => bytecode.push(0x8E),
665            JvmInstruction::D2l => bytecode.push(0x8F),
666            JvmInstruction::D2f => bytecode.push(0x90),
667            JvmInstruction::I2b => bytecode.push(0x91),
668            JvmInstruction::I2c => bytecode.push(0x92),
669            JvmInstruction::I2s => bytecode.push(0x93),
670
671            JvmInstruction::JsrW { target } => {
672                jump_patches.push((pos, pos + 1, target.clone(), true));
673                bytecode.push(0xC9); // jsr_w
674                bytecode.push(0);
675                bytecode.push(0);
676                bytecode.push(0);
677                bytecode.push(0);
678            }
679
680            JvmInstruction::Lookupswitch { default, npairs, match_offsets } => {
681                bytecode.push(0xAB); // lookupswitch
682
683                // 填充以对齐到 4 字节边界
684                let padding = (4 - (bytecode.len() % 4)) % 4;
685                for _ in 0..padding {
686                    bytecode.push(0);
687                }
688
689                // default 偏移量
690                let default_patch_pos = bytecode.len();
691                jump_patches.push((pos, default_patch_pos, default.clone(), true));
692                bytecode.push(0);
693                bytecode.push(0);
694                bytecode.push(0);
695                bytecode.push(0);
696
697                // npairs
698                bytecode.push((*npairs >> 24) as u8);
699                bytecode.push((*npairs >> 16) as u8);
700                bytecode.push((*npairs >> 8) as u8);
701                bytecode.push(*npairs as u8);
702
703                // match-offset pairs
704                for (val, target) in match_offsets {
705                    // match
706                    bytecode.push((val >> 24) as u8);
707                    bytecode.push((val >> 16) as u8);
708                    bytecode.push((val >> 8) as u8);
709                    bytecode.push(*val as u8);
710
711                    // offset
712                    let patch_pos = bytecode.len();
713                    jump_patches.push((pos, patch_pos, target.clone(), true));
714                    bytecode.push(0);
715                    bytecode.push(0);
716                    bytecode.push(0);
717                    bytecode.push(0);
718                }
719            }
720            JvmInstruction::Tableswitch { default, low, high, offsets } => {
721                bytecode.push(0xAA); // tableswitch
722
723                // 填充以对齐到 4 字节边界
724                let padding = (4 - (bytecode.len() % 4)) % 4;
725                for _ in 0..padding {
726                    bytecode.push(0);
727                }
728
729                // default 偏移量
730                let default_patch_pos = bytecode.len();
731                jump_patches.push((pos, default_patch_pos, default.clone(), true));
732                bytecode.push(0);
733                bytecode.push(0);
734                bytecode.push(0);
735                bytecode.push(0);
736
737                // low
738                bytecode.push((*low >> 24) as u8);
739                bytecode.push((*low >> 16) as u8);
740                bytecode.push((*low >> 8) as u8);
741                bytecode.push(*low as u8);
742
743                // high
744                bytecode.push((*high >> 24) as u8);
745                bytecode.push((*high >> 16) as u8);
746                bytecode.push((*high >> 8) as u8);
747                bytecode.push(*high as u8);
748
749                // jump offsets
750                for target in offsets {
751                    let patch_pos = bytecode.len();
752                    jump_patches.push((pos, patch_pos, target.clone(), true));
753                    bytecode.push(0);
754                    bytecode.push(0);
755                    bytecode.push(0);
756                    bytecode.push(0);
757                }
758            }
759            JvmInstruction::Wide => {
760                // Wide 通常作为前缀处理,这里作为一个独立指令可能不需要显式生成
761                // 或者在 emit_instruction 之前由调用者处理。
762                // 如果作为一个独立指令,我们生成 0xC4
763                bytecode.push(0xC4);
764            }
765            JvmInstruction::Label { .. } => {
766                // Label 不生成字节码
767            }
768        }
769    }
770}