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