Skip to main content

jvm_assembler/formats/class/writer/
mod.rs

1#![doc = include_str!("readme.md")]
2//! JVM Class 文件写入器
3//!
4//! 这个模块实现了将 JVM 程序转换为 Class 文件字节码的功能。
5
6use crate::program::*;
7use byteorder::BigEndian;
8use gaia_types::{BinaryWriter, GaiaDiagnostics, Result};
9use std::{collections::HashMap, io::Write};
10
11/// Class 文件写入器
12pub struct ClassWriter<W> {
13    /// 二进制汇编器
14    writer: BinaryWriter<W, BigEndian>,
15    /// 常量池条目
16    cp_entries: Vec<CpEntry>,
17    /// 常量池查找表
18    cp_map: HashMap<CpEntry, u16>,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22enum CpEntry {
23    Utf8(String),
24    Class(u16),
25    String(u16),
26    Fieldref(u16, u16),
27    Methodref(u16, u16),
28    InterfaceMethodref(u16, u16),
29    NameAndType(u16, u16),
30    Integer(i32),
31    Float(u32),
32    Long(i64),
33    Double(u64),
34}
35
36impl<W> ClassWriter<W> {
37    /// 创建新的 Class 写入器
38    pub fn new(writer: W) -> Self {
39        Self { writer: BinaryWriter::new(writer), cp_entries: Vec::new(), cp_map: HashMap::new() }
40    }
41
42    /// 添加 Utf8 常量
43    fn add_utf8(&mut self, s: String) -> u16 {
44        self.add_cp_entry(CpEntry::Utf8(s))
45    }
46
47    /// 添加 Class 常量
48    fn add_class(&mut self, name: String) -> u16 {
49        let name_index = self.add_utf8(name);
50        self.add_cp_entry(CpEntry::Class(name_index))
51    }
52
53    /// 添加 String 常量
54    fn add_string(&mut self, value: String) -> u16 {
55        let utf8_index = self.add_utf8(value);
56        self.add_cp_entry(CpEntry::String(utf8_index))
57    }
58
59    /// 添加 NameAndType 常量
60    fn add_name_and_type(&mut self, name: String, descriptor: String) -> u16 {
61        let name_index = self.add_utf8(name);
62        let descriptor_index = self.add_utf8(descriptor);
63        self.add_cp_entry(CpEntry::NameAndType(name_index, descriptor_index))
64    }
65
66    /// 添加 Fieldref 常量
67    fn add_field_ref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
68        let class_index = self.add_class(class_name);
69        let name_and_type_index = self.add_name_and_type(name, descriptor);
70        self.add_cp_entry(CpEntry::Fieldref(class_index, name_and_type_index))
71    }
72
73    /// 添加 Methodref 常量
74    fn add_method_ref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
75        let class_index = self.add_class(class_name);
76        let name_and_type_index = self.add_name_and_type(name, descriptor);
77        self.add_cp_entry(CpEntry::Methodref(class_index, name_and_type_index))
78    }
79
80    /// 添加 InterfaceMethodref 常量
81    fn add_interface_method_ref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
82        let class_index = self.add_class(class_name);
83        let name_and_type_index = self.add_name_and_type(name, descriptor);
84        self.add_cp_entry(CpEntry::InterfaceMethodref(class_index, name_and_type_index))
85    }
86
87    /// 添加 Integer 常量
88    fn add_int(&mut self, val: i32) -> u16 {
89        self.add_cp_entry(CpEntry::Integer(val))
90    }
91
92    /// 添加 Float 常量
93    fn add_float(&mut self, val: f32) -> u16 {
94        self.add_cp_entry(CpEntry::Float(val.to_bits()))
95    }
96
97    /// 添加 Long 常量
98    fn add_long(&mut self, val: i64) -> u16 {
99        self.add_cp_entry(CpEntry::Long(val))
100    }
101
102    /// 添加 Double 常量
103    fn add_double(&mut self, val: f64) -> u16 {
104        self.add_cp_entry(CpEntry::Double(val.to_bits()))
105    }
106
107    fn add_cp_entry(&mut self, entry: CpEntry) -> u16 {
108        if let Some(&index) = self.cp_map.get(&entry) {
109            return index;
110        }
111
112        let index = (self.cp_entries.len() + 1) as u16;
113        self.cp_entries.push(entry.clone());
114        self.cp_map.insert(entry, index);
115
116        // Long 和 Double 占用两个常量池槽位
117        match self.cp_entries.last().unwrap() {
118            CpEntry::Long(_) | CpEntry::Double(_) => {
119                // 占位符,不实际写入,但增加长度
120                self.cp_entries.push(CpEntry::Utf8("Padding".to_string()));
121            }
122            _ => {}
123        }
124
125        index
126    }
127
128    /// 完成写入并返回底层写入器
129    pub fn finish(self) -> W {
130        self.writer.finish()
131    }
132}
133
134/// 计算 JVM 方法描述符中的参数数量
135fn calculate_parameter_count(descriptor: &str) -> usize {
136    if !descriptor.starts_with('(') {
137        return 0;
138    }
139
140    let mut count = 0;
141    let mut chars = descriptor.chars().skip(1); // 跳过 '('
142
143    while let Some(c) = chars.next() {
144        if c == ')' {
145            break;
146        }
147
148        match c {
149            'L' => {
150                // 引用类型,跳过直到 ';'
151                while let Some(c) = chars.next() {
152                    if c == ';' {
153                        break;
154                    }
155                }
156                count += 1;
157            }
158            '[' => {
159                // 数组类型,跳过直到基本类型或引用类型
160                while let Some(c) = chars.next() {
161                    if c == '[' {
162                        continue;
163                    }
164                    if c == 'L' {
165                        while let Some(c) = chars.next() {
166                            if c == ';' {
167                                break;
168                            }
169                        }
170                    }
171                    break;
172                }
173                count += 1;
174            }
175            'J' | 'D' => {
176                // long 和 double 占用两个槽位
177                count += 2;
178            }
179            _ => {
180                // 其他基本类型 (I, S, B, C, Z, F)
181                count += 1;
182            }
183        }
184    }
185
186    count
187}
188
189impl<W: Write> ClassWriter<W> {
190    /// 将 ClassView 写入为二进制 Class 格式
191    pub fn write(mut self, program: &JvmProgram) -> GaiaDiagnostics<W> {
192        match self.write_class_file(program) {
193            Ok(_) => GaiaDiagnostics::success(self.finish()),
194            Err(error) => GaiaDiagnostics::failure(error),
195        }
196    }
197
198    fn collect_attribute_constants(&mut self, attribute: &JvmAttribute) {
199        match attribute {
200            JvmAttribute::SourceFile { filename } => {
201                self.add_utf8("SourceFile".to_string());
202                self.add_utf8(filename.clone());
203            }
204            JvmAttribute::ConstantValue { value } => {
205                self.add_utf8("ConstantValue".to_string());
206                match value {
207                    JvmConstantPoolEntry::Integer { .. } => {}
208                    JvmConstantPoolEntry::Float { .. } => {}
209                    JvmConstantPoolEntry::Long { .. } => {}
210                    JvmConstantPoolEntry::Double { .. } => {}
211                    JvmConstantPoolEntry::String { value } => {
212                        self.add_string(value.clone());
213                    }
214                    _ => {}
215                }
216            }
217            JvmAttribute::Exceptions { exceptions } => {
218                self.add_utf8("Exceptions".to_string());
219                for exc in exceptions {
220                    self.add_class(exc.clone());
221                }
222            }
223            JvmAttribute::Signature { signature } => {
224                self.add_utf8("Signature".to_string());
225                self.add_utf8(signature.clone());
226            }
227            JvmAttribute::StackMapTable { frames } => {
228                self.add_utf8("StackMapTable".to_string());
229                for frame in frames {
230                    match frame {
231                        JvmStackMapFrame::SameLocals1StackItem { stack, .. }
232                        | JvmStackMapFrame::SameLocals1StackItemExtended { stack, .. } => {
233                            self.collect_verification_type_constants(stack);
234                        }
235                        JvmStackMapFrame::Append { locals, .. } => {
236                            for vt in locals {
237                                self.collect_verification_type_constants(vt);
238                            }
239                        }
240                        JvmStackMapFrame::Full { locals, stack, .. } => {
241                            for vt in locals {
242                                self.collect_verification_type_constants(vt);
243                            }
244                            for vt in stack {
245                                self.collect_verification_type_constants(vt);
246                            }
247                        }
248                        _ => {}
249                    }
250                }
251            }
252            JvmAttribute::InnerClasses { classes } => {
253                self.add_utf8("InnerClasses".to_string());
254                for inner in classes {
255                    self.add_class(inner.inner_class.clone());
256                    if let Some(outer) = &inner.outer_class {
257                        self.add_class(outer.clone());
258                    }
259                    if let Some(name) = &inner.inner_name {
260                        self.add_utf8(name.clone());
261                    }
262                }
263            }
264            JvmAttribute::EnclosingMethod { class_name, method_name, method_descriptor } => {
265                self.add_utf8("EnclosingMethod".to_string());
266                self.add_class(class_name.clone());
267                if let (Some(name), Some(desc)) = (method_name, method_descriptor) {
268                    self.add_name_and_type(name.clone(), desc.clone());
269                }
270            }
271            JvmAttribute::Code { attributes, exception_table, .. } => {
272                self.add_utf8("Code".to_string());
273                for attr in attributes {
274                    self.collect_attribute_constants(attr);
275                }
276                for handler in exception_table {
277                    if handler.catch_type_index > 0 {
278                        // catch_type_index 已经在常量池中了,这里不需要额外操作
279                        // 因为 RawExceptionHandler 是已经转换后的二进制表示
280                    }
281                }
282            }
283            JvmAttribute::LineNumberTable { .. } => {
284                self.add_utf8("LineNumberTable".to_string());
285            }
286            JvmAttribute::LocalVariableTable { entries } => {
287                self.add_utf8("LocalVariableTable".to_string());
288                for entry in entries {
289                    self.add_utf8(entry.name.clone());
290                    self.add_utf8(entry.descriptor.clone());
291                }
292            }
293            JvmAttribute::Unknown { name, .. } => {
294                self.add_utf8(name.clone());
295            }
296        }
297    }
298
299    fn collect_verification_type_constants(&mut self, vt: &JvmVerificationType) {
300        if let JvmVerificationType::Object { class_name } = vt {
301            self.add_class(class_name.clone());
302        }
303    }
304
305    /// 写入 Class 文件
306    fn write_class_file(&mut self, program: &JvmProgram) -> Result<()> {
307        // 1. 预收集所有常量
308        let this_class_idx = self.add_class(program.name.clone());
309        let super_class_idx = if let Some(super_name) = &program.super_class {
310            self.add_class(super_name.clone())
311        }
312        else {
313            self.add_class("java/lang/Object".to_string())
314        };
315
316        // 收集类属性常量
317        for attr in &program.attributes {
318            self.collect_attribute_constants(attr);
319        }
320
321        // 收集字段常量
322        for field in &program.fields {
323            self.add_utf8(field.name.clone());
324            self.add_utf8(field.descriptor.clone());
325            for attr in &field.attributes {
326                self.collect_attribute_constants(attr);
327            }
328            if field.constant_value.is_some() {
329                self.add_utf8("ConstantValue".to_string());
330            }
331        }
332
333        // 收集方法常量
334        let code_utf8_idx = self.add_utf8("Code".to_string());
335        for method in &program.methods {
336            self.add_utf8(method.name.clone());
337            self.add_utf8(method.descriptor.clone());
338
339            for handler in &method.exception_handlers {
340                if let Some(catch_type) = &handler.catch_type {
341                    self.add_class(catch_type.clone());
342                }
343            }
344
345            for attr in &method.attributes {
346                self.collect_attribute_constants(attr);
347            }
348            if !method.exceptions.is_empty() {
349                self.add_utf8("Exceptions".to_string());
350            }
351
352            // 预生成字节码以获取标签位置,用于 StackMapTable 生成
353            let (_, label_positions) = self.generate_method_bytecode(method);
354
355            if program.version.major >= 50 {
356                self.add_utf8("StackMapTable".to_string());
357                // 如果需要自动生成 StackMapTable,预先收集其常量
358                let has_stack_map = method.attributes.iter().any(|a| matches!(a, JvmAttribute::StackMapTable { .. }));
359                if !has_stack_map {
360                    let analyzer = crate::analyzer::StackMapAnalyzer::new(program.name.clone(), method, &label_positions);
361                    let frames = analyzer.analyze();
362                    for frame in &frames {
363                        match frame {
364                            JvmStackMapFrame::SameLocals1StackItem { stack, .. }
365                            | JvmStackMapFrame::SameLocals1StackItemExtended { stack, .. } => {
366                                self.collect_verification_type_constants(stack);
367                            }
368                            JvmStackMapFrame::Append { locals, .. } => {
369                                for vt in locals {
370                                    self.collect_verification_type_constants(vt);
371                                }
372                            }
373                            JvmStackMapFrame::Full { locals, stack, .. } => {
374                                for vt in locals {
375                                    self.collect_verification_type_constants(vt);
376                                }
377                                for vt in stack {
378                                    self.collect_verification_type_constants(vt);
379                                }
380                            }
381                            _ => {}
382                        }
383                    }
384                }
385            }
386
387            // 收集指令中的常量
388            for inst in &method.instructions {
389                match inst {
390                    JvmInstruction::Ldc { symbol } | JvmInstruction::LdcW { symbol } | JvmInstruction::Ldc2W { symbol } => {
391                        self.add_string(symbol.clone());
392                    }
393                    JvmInstruction::Getstatic { class_name, field_name, descriptor }
394                    | JvmInstruction::Putstatic { class_name, field_name, descriptor }
395                    | JvmInstruction::Getfield { class_name, field_name, descriptor }
396                    | JvmInstruction::Putfield { class_name, field_name, descriptor } => {
397                        self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
398                    }
399                    JvmInstruction::Invokevirtual { class_name, method_name, descriptor }
400                    | JvmInstruction::Invokespecial { class_name, method_name, descriptor }
401                    | JvmInstruction::Invokestatic { class_name, method_name, descriptor }
402                    | JvmInstruction::Invokedynamic { class_name, method_name, descriptor } => {
403                        self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
404                    }
405                    JvmInstruction::Invokeinterface { class_name, method_name, descriptor } => {
406                        self.add_interface_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
407                    }
408                    JvmInstruction::New { class_name }
409                    | JvmInstruction::Anewarray { class_name }
410                    | JvmInstruction::Checkcast { class_name }
411                    | JvmInstruction::Instanceof { class_name }
412                    | JvmInstruction::Multianewarray { class_name, .. } => {
413                        self.add_class(class_name.clone());
414                    }
415                    _ => {}
416                }
417            }
418        }
419
420        // 2. 开始写入
421        // 写入魔数
422        self.writer.write_u32(0xCAFEBABE)?;
423
424        // 写入版本信息
425        self.writer.write_u16(program.version.minor)?;
426        self.writer.write_u16(program.version.major)?;
427
428        // 写入常量池
429        self.write_constant_pool()?;
430
431        // 写入访问标志
432        self.writer.write_u16(program.access_flags.to_flags())?;
433
434        // 写入类索引(this_class)
435        self.writer.write_u16(this_class_idx)?;
436
437        // 写入超类索引(super_class)
438        self.writer.write_u16(super_class_idx)?;
439
440        // 写入接口数量(暂时为0)
441        self.writer.write_u16(0)?;
442
443        // 写入字段
444        self.write_fields(program)?;
445
446        // 写入方法
447        self.write_methods(program, code_utf8_idx)?;
448
449        // 写入类属性
450        self.writer.write_u16(program.attributes.len() as u16)?;
451        for attr in &program.attributes {
452            self.write_attribute(attr)?;
453        }
454
455        Ok(())
456    }
457
458    /// 写入常量池
459    fn write_constant_pool(&mut self) -> Result<()> {
460        // 写入常量池计数(+1 因为索引从1开始)
461        self.writer.write_u16((self.cp_entries.len() + 1) as u16)?;
462
463        // 写入常量池条目
464        let mut i = 0;
465        while i < self.cp_entries.len() {
466            let entry = &self.cp_entries[i];
467            match entry {
468                CpEntry::Utf8(s) => {
469                    self.writer.write_u8(1)?; // CONSTANT_Utf8 tag
470                    self.writer.write_u16(s.len() as u16)?;
471                    self.writer.write_all(s.as_bytes())?;
472                }
473                CpEntry::Class(name_idx) => {
474                    self.writer.write_u8(7)?; // CONSTANT_Class tag
475                    self.writer.write_u16(*name_idx)?;
476                }
477                CpEntry::String(utf8_idx) => {
478                    self.writer.write_u8(8)?; // CONSTANT_String tag
479                    self.writer.write_u16(*utf8_idx)?;
480                }
481                CpEntry::NameAndType(name_idx, desc_idx) => {
482                    self.writer.write_u8(12)?; // CONSTANT_NameAndType tag
483                    self.writer.write_u16(*name_idx)?;
484                    self.writer.write_u16(*desc_idx)?;
485                }
486                CpEntry::Fieldref(class_idx, nt_idx) => {
487                    self.writer.write_u8(9)?; // CONSTANT_Fieldref tag
488                    self.writer.write_u16(*class_idx)?;
489                    self.writer.write_u16(*nt_idx)?;
490                }
491                CpEntry::Methodref(class_idx, nt_idx) => {
492                    self.writer.write_u8(10)?; // CONSTANT_Methodref tag
493                    self.writer.write_u16(*class_idx)?;
494                    self.writer.write_u16(*nt_idx)?;
495                }
496                CpEntry::InterfaceMethodref(class_idx, nt_idx) => {
497                    self.writer.write_u8(11)?; // CONSTANT_InterfaceMethodref tag
498                    self.writer.write_u16(*class_idx)?;
499                    self.writer.write_u16(*nt_idx)?;
500                }
501                CpEntry::Integer(val) => {
502                    self.writer.write_u8(3)?; // CONSTANT_Integer tag
503                    self.writer.write_i32(*val)?;
504                }
505                CpEntry::Float(bits) => {
506                    self.writer.write_u8(4)?; // CONSTANT_Float tag
507                    self.writer.write_u32(*bits)?;
508                }
509                CpEntry::Long(val) => {
510                    self.writer.write_u8(5)?; // CONSTANT_Long tag
511                    self.writer.write_i64(*val)?;
512                    i += 1; // Long 占用两个槽位
513                }
514                CpEntry::Double(bits) => {
515                    self.writer.write_u8(6)?; // CONSTANT_Double tag
516                    self.writer.write_u64(*bits)?;
517                    i += 1; // Double 占用两个槽位
518                }
519            }
520            i += 1;
521        }
522
523        Ok(())
524    }
525
526    /// 写入字段
527    fn write_fields(&mut self, program: &JvmProgram) -> Result<()> {
528        self.writer.write_u16(program.fields.len() as u16)?;
529
530        for field in &program.fields {
531            self.writer.write_u16(field.access_flags.to_flags())?;
532            let name_idx = self.add_utf8(field.name.clone());
533            let desc_idx = self.add_utf8(field.descriptor.clone());
534            self.writer.write_u16(name_idx)?;
535            self.writer.write_u16(desc_idx)?;
536
537            // 计算属性数量
538            let mut attr_count = field.attributes.len() as u16;
539            if field.constant_value.is_some() {
540                attr_count += 1;
541            }
542            self.writer.write_u16(attr_count)?;
543
544            // 写入 ConstantValue 属性
545            if let Some(val) = &field.constant_value {
546                self.write_attribute(&JvmAttribute::ConstantValue { value: val.clone() })?;
547            }
548
549            // 写入其他属性
550            for attr in &field.attributes {
551                self.write_attribute(attr)?;
552            }
553        }
554
555        Ok(())
556    }
557
558    /// 写入方法
559    fn write_methods(&mut self, program: &JvmProgram, code_utf8_idx: u16) -> Result<()> {
560        self.writer.write_u16(program.methods.len() as u16)?;
561
562        let exceptions_utf8_idx = self.add_utf8("Exceptions".to_string());
563
564        for method in &program.methods {
565            self.writer.write_u16(method.access_flags.to_flags())?;
566            let name_idx = self.add_utf8(method.name.clone());
567            let desc_idx = self.add_utf8(method.descriptor.clone());
568            self.writer.write_u16(name_idx)?;
569            self.writer.write_u16(desc_idx)?;
570
571            // 计算属性数量
572            let mut attribute_count = 1; // 总是包含 Code 属性
573            if !method.exceptions.is_empty() {
574                attribute_count += 1;
575            }
576            attribute_count += method.attributes.len() as u16;
577
578            // 写入属性数量
579            self.writer.write_u16(attribute_count)?;
580
581            // 1. 写入 Code 属性
582            self.write_code_attribute(program, method, code_utf8_idx)?;
583
584            // 2. 写入 Exceptions 属性
585            if !method.exceptions.is_empty() {
586                self.writer.write_u16(exceptions_utf8_idx)?;
587                let attr_len = 2 + method.exceptions.len() * 2;
588                self.writer.write_u32(attr_len as u32)?;
589                self.writer.write_u16(method.exceptions.len() as u16)?;
590                for exc in &method.exceptions {
591                    let exc_idx = self.add_class(exc.clone());
592                    self.writer.write_u16(exc_idx)?;
593                }
594            }
595
596            // 3. 写入其他属性
597            for attr in &method.attributes {
598                self.write_attribute(attr)?;
599            }
600        }
601
602        Ok(())
603    }
604
605    /// 写入 Code 属性
606    fn write_code_attribute(&mut self, program: &JvmProgram, method: &JvmMethod, code_utf8_idx: u16) -> Result<()> {
607        // Code 属性名称索引
608        self.writer.write_u16(code_utf8_idx)?;
609
610        let (bytecode, label_positions) = self.generate_method_bytecode(method);
611
612        // 解析异常表
613        let mut raw_exception_table = Vec::new();
614        for handler in &method.exception_handlers {
615            let start_pc = *label_positions.get(&handler.start_label).unwrap_or(&0) as u16;
616            let end_pc = *label_positions.get(&handler.end_label).unwrap_or(&0) as u16;
617            let handler_pc = *label_positions.get(&handler.handler_label).unwrap_or(&0) as u16;
618            let catch_type_index =
619                if let Some(catch_type) = &handler.catch_type { self.add_class(catch_type.clone()) } else { 0 };
620            raw_exception_table.push(RawExceptionHandler { start_pc, end_pc, handler_pc, catch_type_index });
621        }
622
623        // 收集并准备子属性
624        let mut code_attributes = Vec::new();
625
626        // 自动生成 StackMapTable (如果版本 >= Java 6 且尚未手动提供)
627        if program.version.major >= 50 {
628            let has_stack_map = method.attributes.iter().any(|a| matches!(a, JvmAttribute::StackMapTable { .. }));
629            if !has_stack_map {
630                let analyzer = crate::analyzer::StackMapAnalyzer::new(program.name.clone(), method, &label_positions);
631                let frames = analyzer.analyze();
632                if !frames.is_empty() {
633                    code_attributes.push(JvmAttribute::StackMapTable { frames });
634                }
635            }
636        }
637
638        // 准备子属性数据
639        let mut sub_attr_buf = Vec::new();
640        // 这里需要临时替换 writer 以写入到缓冲区
641        let mut temp_writer = ClassWriter {
642            writer: BinaryWriter::new(&mut sub_attr_buf),
643            cp_entries: self.cp_entries.clone(),
644            cp_map: self.cp_map.clone(),
645        };
646
647        // 写入自动生成的属性
648        for attr in &code_attributes {
649            temp_writer.write_attribute(attr)?;
650        }
651        // 写入原有的属性 (假设它们是 Code 属性的子属性,目前简化处理)
652        // 注意:在实际 JVM 中,LineNumberTable 等是 Code 的子属性
653        // 我们目前的结构中,JvmMethod.attributes 包含了所有属性
654        // 需要区分哪些是方法属性,哪些是 Code 子属性
655        // 这里暂时只处理自动生成的
656
657        // 同步常量池
658        self.cp_entries = temp_writer.cp_entries;
659        self.cp_map = temp_writer.cp_map;
660
661        // 计算总长度
662        let exception_table_len = raw_exception_table.len() * 8;
663        let attribute_length = 2 + 2 + 4 + bytecode.len() + 2 + exception_table_len + 2 + sub_attr_buf.len();
664        self.writer.write_u32(attribute_length as u32)?;
665
666        // max_stack 和 max_locals
667        self.writer.write_u16(method.max_stack)?;
668        self.writer.write_u16(method.max_locals)?;
669
670        // 字节码长度和字节码
671        self.writer.write_u32(bytecode.len() as u32)?;
672        self.writer.write_all(&bytecode)?;
673
674        // 异常表
675        self.writer.write_u16(raw_exception_table.len() as u16)?;
676        for handler in raw_exception_table {
677            self.writer.write_u16(handler.start_pc)?;
678            self.writer.write_u16(handler.end_pc)?;
679            self.writer.write_u16(handler.handler_pc)?;
680            self.writer.write_u16(handler.catch_type_index)?;
681        }
682
683        // 子属性数量
684        self.writer.write_u16(code_attributes.len() as u16)?;
685        self.writer.write_all(&sub_attr_buf)?;
686
687        Ok(())
688    }
689
690    /// 生成方法的字节码及标签位置
691    fn generate_method_bytecode(&mut self, method: &JvmMethod) -> (Vec<u8>, HashMap<String, i32>) {
692        let mut bytecode = Vec::new();
693        let mut label_positions = HashMap::new();
694        let mut jump_patches = Vec::new(); // (instr_pos, patch_pos, target_label_name, is_wide)
695
696        // 第一遍:计算指令位置并记录标签位置
697        for instruction in &method.instructions {
698            match instruction {
699                JvmInstruction::Label { name } => {
700                    label_positions.insert(name.clone(), bytecode.len() as i32);
701                }
702                _ => {
703                    let pos = bytecode.len();
704                    self.emit_instruction(instruction, &mut bytecode, &mut jump_patches, pos);
705                }
706            }
707        }
708
709        // 第二遍:解析跳转偏移量
710        for (instr_pos, patch_pos, target_name, is_wide) in jump_patches {
711            if let Some(&target_pos) = label_positions.get(&target_name) {
712                let offset = target_pos - instr_pos as i32;
713                if is_wide {
714                    // 4 字节偏移量
715                    bytecode[patch_pos] = ((offset >> 24) & 0xFF) as u8;
716                    bytecode[patch_pos + 1] = ((offset >> 16) & 0xFF) as u8;
717                    bytecode[patch_pos + 2] = ((offset >> 8) & 0xFF) as u8;
718                    bytecode[patch_pos + 3] = (offset & 0xFF) as u8;
719                }
720                else {
721                    // 2 字节偏移量
722                    bytecode[patch_pos] = ((offset >> 8) & 0xFF) as u8;
723                    bytecode[patch_pos + 1] = (offset & 0xFF) as u8;
724                }
725            }
726        }
727
728        // 如果方法没有指令,添加一个 return 指令
729        if bytecode.is_empty() {
730            bytecode.push(0xB1); // return
731        }
732
733        (bytecode, label_positions)
734    }
735
736    /// 写入属性
737    fn write_attribute(&mut self, attribute: &JvmAttribute) -> Result<()> {
738        match attribute {
739            JvmAttribute::SourceFile { filename } => {
740                let name_idx = self.add_utf8("SourceFile".to_string());
741                let file_idx = self.add_utf8(filename.clone());
742                self.writer.write_u16(name_idx)?;
743                self.writer.write_u32(2)?;
744                self.writer.write_u16(file_idx)?;
745            }
746            JvmAttribute::ConstantValue { value } => {
747                let name_idx = self.add_utf8("ConstantValue".to_string());
748                let val_idx = match value {
749                    JvmConstantPoolEntry::Integer { value } => self.add_int(*value),
750                    JvmConstantPoolEntry::Float { value } => self.add_float(*value),
751                    JvmConstantPoolEntry::Long { value } => self.add_long(*value),
752                    JvmConstantPoolEntry::Double { value } => self.add_double(*value),
753                    JvmConstantPoolEntry::String { value } => self.add_string(value.clone()),
754                    _ => 0,
755                };
756                self.writer.write_u16(name_idx)?;
757                self.writer.write_u32(2)?;
758                self.writer.write_u16(val_idx)?;
759            }
760            JvmAttribute::Exceptions { exceptions } => {
761                let name_idx = self.add_utf8("Exceptions".to_string());
762                let attr_len = 2 + exceptions.len() * 2;
763                self.writer.write_u16(name_idx)?;
764                self.writer.write_u32(attr_len as u32)?;
765                self.writer.write_u16(exceptions.len() as u16)?;
766                for exc in exceptions {
767                    let exc_idx = self.add_class(exc.clone());
768                    self.writer.write_u16(exc_idx)?;
769                }
770            }
771            JvmAttribute::Signature { signature } => {
772                let name_idx = self.add_utf8("Signature".to_string());
773                let sig_idx = self.add_utf8(signature.clone());
774                self.writer.write_u16(name_idx)?;
775                self.writer.write_u32(2)?;
776                self.writer.write_u16(sig_idx)?;
777            }
778            JvmAttribute::StackMapTable { frames } => {
779                let name_idx = self.add_utf8("StackMapTable".to_string());
780                let mut buf = Vec::new();
781                buf.extend_from_slice(&(frames.len() as u16).to_be_bytes());
782                for frame in frames {
783                    self.write_stack_map_frame_to_buf(frame, &mut buf)?;
784                }
785                self.writer.write_u16(name_idx)?;
786                self.writer.write_u32(buf.len() as u32)?;
787                self.writer.write_all(&buf)?;
788            }
789            JvmAttribute::InnerClasses { classes } => {
790                let name_idx = self.add_utf8("InnerClasses".to_string());
791                let attr_len = 2 + classes.len() * 8;
792                self.writer.write_u16(name_idx)?;
793                self.writer.write_u32(attr_len as u32)?;
794                self.writer.write_u16(classes.len() as u16)?;
795                for inner in classes {
796                    let inner_idx = self.add_class(inner.inner_class.clone());
797                    let outer_idx = if let Some(outer) = &inner.outer_class { self.add_class(outer.clone()) } else { 0 };
798                    let name_idx = if let Some(name) = &inner.inner_name { self.add_utf8(name.clone()) } else { 0 };
799                    self.writer.write_u16(inner_idx)?;
800                    self.writer.write_u16(outer_idx)?;
801                    self.writer.write_u16(name_idx)?;
802                    self.writer.write_u16(inner.access_flags.to_flags())?;
803                }
804            }
805            JvmAttribute::EnclosingMethod { class_name, method_name, method_descriptor } => {
806                let name_idx = self.add_utf8("EnclosingMethod".to_string());
807                let class_idx = self.add_class(class_name.clone());
808                let nt_idx = if let (Some(name), Some(desc)) = (method_name, method_descriptor) {
809                    self.add_name_and_type(name.clone(), desc.clone())
810                }
811                else {
812                    0
813                };
814                self.writer.write_u16(name_idx)?;
815                self.writer.write_u32(4)?;
816                self.writer.write_u16(class_idx)?;
817                self.writer.write_u16(nt_idx)?;
818            }
819            JvmAttribute::Unknown { name, data } => {
820                let name_idx = self.add_utf8(name.clone());
821                self.writer.write_u16(name_idx)?;
822                self.writer.write_u32(data.len() as u32)?;
823                self.writer.write_all(data)?;
824            }
825            _ => {
826                // Code, LineNumberTable, LocalVariableTable 等需要特殊处理或暂不支持
827            }
828        }
829        Ok(())
830    }
831
832    fn write_verification_type_to_buf(&mut self, vt: &JvmVerificationType, buf: &mut Vec<u8>) -> Result<()> {
833        match vt {
834            JvmVerificationType::Top => buf.push(0),
835            JvmVerificationType::Integer => buf.push(1),
836            JvmVerificationType::Float => buf.push(2),
837            JvmVerificationType::Double => buf.push(3),
838            JvmVerificationType::Long => buf.push(4),
839            JvmVerificationType::Null => buf.push(5),
840            JvmVerificationType::UninitializedThis => buf.push(6),
841            JvmVerificationType::Object { class_name } => {
842                buf.push(7);
843                let class_idx = self.add_class(class_name.clone());
844                buf.extend_from_slice(&class_idx.to_be_bytes());
845            }
846            JvmVerificationType::Uninitialized { offset } => {
847                buf.push(8);
848                buf.extend_from_slice(&offset.to_be_bytes());
849            }
850        }
851        Ok(())
852    }
853
854    fn write_stack_map_frame_to_buf(&mut self, frame: &JvmStackMapFrame, buf: &mut Vec<u8>) -> Result<()> {
855        match frame {
856            JvmStackMapFrame::Same { offset_delta } => {
857                if *offset_delta <= 63 {
858                    buf.push(*offset_delta as u8);
859                }
860                else {
861                    buf.push(251);
862                    buf.extend_from_slice(&offset_delta.to_be_bytes());
863                }
864            }
865            JvmStackMapFrame::SameLocals1StackItem { offset_delta, stack } => {
866                if *offset_delta <= 63 {
867                    buf.push((*offset_delta + 64) as u8);
868                    self.write_verification_type_to_buf(stack, buf)?;
869                }
870                else {
871                    buf.push(247);
872                    buf.extend_from_slice(&offset_delta.to_be_bytes());
873                    self.write_verification_type_to_buf(stack, buf)?;
874                }
875            }
876            JvmStackMapFrame::SameLocals1StackItemExtended { offset_delta, stack } => {
877                buf.push(247);
878                buf.extend_from_slice(&offset_delta.to_be_bytes());
879                self.write_verification_type_to_buf(stack, buf)?;
880            }
881            JvmStackMapFrame::Chop { offset_delta, k } => {
882                buf.push(251 - k);
883                buf.extend_from_slice(&offset_delta.to_be_bytes());
884            }
885            JvmStackMapFrame::SameExtended { offset_delta } => {
886                buf.push(251);
887                buf.extend_from_slice(&offset_delta.to_be_bytes());
888            }
889            JvmStackMapFrame::Append { offset_delta, locals } => {
890                buf.push((251 + locals.len()) as u8);
891                buf.extend_from_slice(&offset_delta.to_be_bytes());
892                for vt in locals {
893                    self.write_verification_type_to_buf(vt, buf)?;
894                }
895            }
896            JvmStackMapFrame::Full { offset_delta, locals, stack } => {
897                buf.push(255);
898                buf.extend_from_slice(&offset_delta.to_be_bytes());
899                buf.extend_from_slice(&(locals.len() as u16).to_be_bytes());
900                for vt in locals {
901                    self.write_verification_type_to_buf(vt, buf)?;
902                }
903                buf.extend_from_slice(&(stack.len() as u16).to_be_bytes());
904                for vt in stack {
905                    self.write_verification_type_to_buf(vt, buf)?;
906                }
907            }
908        }
909        Ok(())
910    }
911
912    /// 发射单条指令的字节码
913    fn emit_instruction(
914        &mut self,
915        instruction: &JvmInstruction,
916        bytecode: &mut Vec<u8>,
917        jump_patches: &mut Vec<(usize, usize, String, bool)>,
918        pos: usize,
919    ) {
920        match instruction {
921            JvmInstruction::Nop => bytecode.push(0x00),
922            JvmInstruction::AconstNull => bytecode.push(0x01),
923            JvmInstruction::IconstM1 => bytecode.push(0x02),
924            JvmInstruction::Iconst0 => bytecode.push(0x03),
925            JvmInstruction::Iconst1 => bytecode.push(0x04),
926            JvmInstruction::Iconst2 => bytecode.push(0x05),
927            JvmInstruction::Iconst3 => bytecode.push(0x06),
928            JvmInstruction::Iconst4 => bytecode.push(0x07),
929            JvmInstruction::Iconst5 => bytecode.push(0x08),
930            JvmInstruction::Lconst0 => bytecode.push(0x09),
931            JvmInstruction::Lconst1 => bytecode.push(0x0A),
932            JvmInstruction::Fconst0 => bytecode.push(0x0B),
933            JvmInstruction::Fconst1 => bytecode.push(0x0C),
934            JvmInstruction::Fconst2 => bytecode.push(0x0D),
935            JvmInstruction::Dconst0 => bytecode.push(0x0E),
936            JvmInstruction::Dconst1 => bytecode.push(0x0F),
937
938            JvmInstruction::Bipush { value } => {
939                bytecode.push(0x10);
940                bytecode.push(*value as u8);
941            }
942            JvmInstruction::Sipush { value } => {
943                bytecode.push(0x11);
944                bytecode.push((*value >> 8) as u8);
945                bytecode.push((*value & 0xFF) as u8);
946            }
947
948            JvmInstruction::Ldc { symbol } => {
949                let index = self.add_string(symbol.clone());
950                if index < 256 {
951                    bytecode.push(0x12); // ldc
952                    bytecode.push(index as u8);
953                }
954                else {
955                    bytecode.push(0x13); // ldc_w
956                    bytecode.push((index >> 8) as u8);
957                    bytecode.push((index & 0xFF) as u8);
958                }
959            }
960            JvmInstruction::LdcW { symbol } => {
961                let index = self.add_string(symbol.clone());
962                bytecode.push(0x13); // ldc_w
963                bytecode.push((index >> 8) as u8);
964                bytecode.push((index & 0xFF) as u8);
965            }
966            JvmInstruction::Ldc2W { symbol } => {
967                let index = self.add_string(symbol.clone());
968                bytecode.push(0x14); // ldc2_w
969                bytecode.push((index >> 8) as u8);
970                bytecode.push((index & 0xFF) as u8);
971            }
972
973            JvmInstruction::Iload { index } => {
974                if *index <= 3 {
975                    bytecode.push(0x1A + *index as u8);
976                }
977                else if *index <= 255 {
978                    bytecode.push(0x15);
979                    bytecode.push(*index as u8);
980                }
981                else {
982                    bytecode.push(0xC4); // wide
983                    bytecode.push(0x15);
984                    bytecode.push((*index >> 8) as u8);
985                    bytecode.push((*index & 0xFF) as u8);
986                }
987            }
988            JvmInstruction::Iload0 => bytecode.push(0x1A),
989            JvmInstruction::Iload1 => bytecode.push(0x1B),
990            JvmInstruction::Iload2 => bytecode.push(0x1C),
991            JvmInstruction::Iload3 => bytecode.push(0x1D),
992
993            JvmInstruction::Lload { index } => {
994                if *index <= 3 {
995                    bytecode.push(0x1E + *index as u8);
996                }
997                else if *index <= 255 {
998                    bytecode.push(0x16);
999                    bytecode.push(*index as u8);
1000                }
1001                else {
1002                    bytecode.push(0xC4); // wide
1003                    bytecode.push(0x16);
1004                    bytecode.push((*index >> 8) as u8);
1005                    bytecode.push((*index & 0xFF) as u8);
1006                }
1007            }
1008            JvmInstruction::Lload0 => bytecode.push(0x1E),
1009            JvmInstruction::Lload1 => bytecode.push(0x1F),
1010            JvmInstruction::Lload2 => bytecode.push(0x20),
1011            JvmInstruction::Lload3 => bytecode.push(0x21),
1012
1013            JvmInstruction::Fload { index } => {
1014                if *index <= 3 {
1015                    bytecode.push(0x22 + *index as u8);
1016                }
1017                else if *index <= 255 {
1018                    bytecode.push(0x17);
1019                    bytecode.push(*index as u8);
1020                }
1021                else {
1022                    bytecode.push(0xC4); // wide
1023                    bytecode.push(0x17);
1024                    bytecode.push((*index >> 8) as u8);
1025                    bytecode.push((*index & 0xFF) as u8);
1026                }
1027            }
1028            JvmInstruction::Fload0 => bytecode.push(0x22),
1029            JvmInstruction::Fload1 => bytecode.push(0x23),
1030            JvmInstruction::Fload2 => bytecode.push(0x24),
1031            JvmInstruction::Fload3 => bytecode.push(0x25),
1032
1033            JvmInstruction::Dload { index } => {
1034                if *index <= 3 {
1035                    bytecode.push(0x26 + *index as u8);
1036                }
1037                else if *index <= 255 {
1038                    bytecode.push(0x18);
1039                    bytecode.push(*index as u8);
1040                }
1041                else {
1042                    bytecode.push(0xC4); // wide
1043                    bytecode.push(0x18);
1044                    bytecode.push((*index >> 8) as u8);
1045                    bytecode.push((*index & 0xFF) as u8);
1046                }
1047            }
1048            JvmInstruction::Dload0 => bytecode.push(0x26),
1049            JvmInstruction::Dload1 => bytecode.push(0x27),
1050            JvmInstruction::Dload2 => bytecode.push(0x28),
1051            JvmInstruction::Dload3 => bytecode.push(0x29),
1052
1053            JvmInstruction::Aload { index } => {
1054                if *index <= 3 {
1055                    bytecode.push(0x2A + *index as u8);
1056                }
1057                else if *index <= 255 {
1058                    bytecode.push(0x19);
1059                    bytecode.push(*index as u8);
1060                }
1061                else {
1062                    bytecode.push(0xC4); // wide
1063                    bytecode.push(0x19);
1064                    bytecode.push((*index >> 8) as u8);
1065                    bytecode.push((*index & 0xFF) as u8);
1066                }
1067            }
1068            JvmInstruction::Aload0 => bytecode.push(0x2A),
1069            JvmInstruction::Aload1 => bytecode.push(0x2B),
1070            JvmInstruction::Aload2 => bytecode.push(0x2C),
1071            JvmInstruction::Aload3 => bytecode.push(0x2D),
1072
1073            JvmInstruction::Istore { index } => {
1074                if *index <= 3 {
1075                    bytecode.push(0x3B + *index as u8);
1076                }
1077                else if *index <= 255 {
1078                    bytecode.push(0x36);
1079                    bytecode.push(*index as u8);
1080                }
1081                else {
1082                    bytecode.push(0xC4); // wide
1083                    bytecode.push(0x36);
1084                    bytecode.push((*index >> 8) as u8);
1085                    bytecode.push((*index & 0xFF) as u8);
1086                }
1087            }
1088            JvmInstruction::Istore0 => bytecode.push(0x3B),
1089            JvmInstruction::Istore1 => bytecode.push(0x3C),
1090            JvmInstruction::Istore2 => bytecode.push(0x3D),
1091            JvmInstruction::Istore3 => bytecode.push(0x3E),
1092
1093            JvmInstruction::Lstore { index } => {
1094                if *index <= 3 {
1095                    bytecode.push(0x3F + *index as u8);
1096                }
1097                else if *index <= 255 {
1098                    bytecode.push(0x37);
1099                    bytecode.push(*index as u8);
1100                }
1101                else {
1102                    bytecode.push(0xC4); // wide
1103                    bytecode.push(0x37);
1104                    bytecode.push((*index >> 8) as u8);
1105                    bytecode.push((*index & 0xFF) as u8);
1106                }
1107            }
1108            JvmInstruction::Lstore0 => bytecode.push(0x3F),
1109            JvmInstruction::Lstore1 => bytecode.push(0x40),
1110            JvmInstruction::Lstore2 => bytecode.push(0x41),
1111            JvmInstruction::Lstore3 => bytecode.push(0x42),
1112
1113            JvmInstruction::Fstore { index } => {
1114                if *index <= 3 {
1115                    bytecode.push(0x43 + *index as u8);
1116                }
1117                else if *index <= 255 {
1118                    bytecode.push(0x38);
1119                    bytecode.push(*index as u8);
1120                }
1121                else {
1122                    bytecode.push(0xC4); // wide
1123                    bytecode.push(0x38);
1124                    bytecode.push((*index >> 8) as u8);
1125                    bytecode.push((*index & 0xFF) as u8);
1126                }
1127            }
1128            JvmInstruction::Fstore0 => bytecode.push(0x43),
1129            JvmInstruction::Fstore1 => bytecode.push(0x44),
1130            JvmInstruction::Fstore2 => bytecode.push(0x45),
1131            JvmInstruction::Fstore3 => bytecode.push(0x46),
1132
1133            JvmInstruction::Dstore { index } => {
1134                if *index <= 3 {
1135                    bytecode.push(0x47 + *index as u8);
1136                }
1137                else if *index <= 255 {
1138                    bytecode.push(0x39);
1139                    bytecode.push(*index as u8);
1140                }
1141                else {
1142                    bytecode.push(0xC4); // wide
1143                    bytecode.push(0x39);
1144                    bytecode.push((*index >> 8) as u8);
1145                    bytecode.push((*index & 0xFF) as u8);
1146                }
1147            }
1148            JvmInstruction::Dstore0 => bytecode.push(0x47),
1149            JvmInstruction::Dstore1 => bytecode.push(0x48),
1150            JvmInstruction::Dstore2 => bytecode.push(0x49),
1151            JvmInstruction::Dstore3 => bytecode.push(0x4A),
1152
1153            JvmInstruction::Astore { index } => {
1154                if *index <= 3 {
1155                    bytecode.push(0x4B + *index as u8);
1156                }
1157                else if *index <= 255 {
1158                    bytecode.push(0x3A);
1159                    bytecode.push(*index as u8);
1160                }
1161                else {
1162                    bytecode.push(0xC4); // wide
1163                    bytecode.push(0x3A);
1164                    bytecode.push((*index >> 8) as u8);
1165                    bytecode.push((*index & 0xFF) as u8);
1166                }
1167            }
1168            JvmInstruction::Astore0 => bytecode.push(0x4B),
1169            JvmInstruction::Astore1 => bytecode.push(0x4C),
1170            JvmInstruction::Astore2 => bytecode.push(0x4D),
1171            JvmInstruction::Astore3 => bytecode.push(0x4E),
1172
1173            JvmInstruction::Pop => bytecode.push(0x57),
1174            JvmInstruction::Pop2 => bytecode.push(0x58),
1175            JvmInstruction::Dup => bytecode.push(0x59),
1176            JvmInstruction::DupX1 => bytecode.push(0x5A),
1177            JvmInstruction::DupX2 => bytecode.push(0x5B),
1178            JvmInstruction::Dup2 => bytecode.push(0x5C),
1179            JvmInstruction::Dup2X1 => bytecode.push(0x5D),
1180            JvmInstruction::Dup2X2 => bytecode.push(0x5E),
1181            JvmInstruction::Swap => bytecode.push(0x5F),
1182
1183            JvmInstruction::Iadd => bytecode.push(0x60),
1184            JvmInstruction::Ladd => bytecode.push(0x61),
1185            JvmInstruction::Fadd => bytecode.push(0x62),
1186            JvmInstruction::Dadd => bytecode.push(0x63),
1187            JvmInstruction::Isub => bytecode.push(0x64),
1188            JvmInstruction::Lsub => bytecode.push(0x65),
1189            JvmInstruction::Fsub => bytecode.push(0x66),
1190            JvmInstruction::Dsub => bytecode.push(0x67),
1191            JvmInstruction::Imul => bytecode.push(0x68),
1192            JvmInstruction::Lmul => bytecode.push(0x69),
1193            JvmInstruction::Fmul => bytecode.push(0x6A),
1194            JvmInstruction::Dmul => bytecode.push(0x6B),
1195            JvmInstruction::Idiv => bytecode.push(0x6C),
1196            JvmInstruction::Ldiv => bytecode.push(0x6D),
1197            JvmInstruction::Fdiv => bytecode.push(0x6E),
1198            JvmInstruction::Ddiv => bytecode.push(0x6F),
1199            JvmInstruction::Irem => bytecode.push(0x70),
1200            JvmInstruction::Lrem => bytecode.push(0x71),
1201            JvmInstruction::Frem => bytecode.push(0x72),
1202            JvmInstruction::Drem => bytecode.push(0x73),
1203            JvmInstruction::Ineg => bytecode.push(0x74),
1204            JvmInstruction::Lneg => bytecode.push(0x75),
1205            JvmInstruction::Fneg => bytecode.push(0x76),
1206            JvmInstruction::Dneg => bytecode.push(0x77),
1207
1208            JvmInstruction::Ishl => bytecode.push(0x78),
1209            JvmInstruction::Lshl => bytecode.push(0x79),
1210            JvmInstruction::Ishr => bytecode.push(0x7A),
1211            JvmInstruction::Lshr => bytecode.push(0x7B),
1212            JvmInstruction::Iushr => bytecode.push(0x7C),
1213            JvmInstruction::Lushr => bytecode.push(0x7D),
1214            JvmInstruction::Iand => bytecode.push(0x7E),
1215            JvmInstruction::Land => bytecode.push(0x7F),
1216            JvmInstruction::Ior => bytecode.push(0x80),
1217            JvmInstruction::Lor => bytecode.push(0x81),
1218            JvmInstruction::Ixor => bytecode.push(0x82),
1219            JvmInstruction::Lxor => bytecode.push(0x83),
1220
1221            JvmInstruction::Lcmp => bytecode.push(0x94),
1222            JvmInstruction::Fcmpl => bytecode.push(0x95),
1223            JvmInstruction::Fcmpg => bytecode.push(0x96),
1224            JvmInstruction::Dcmpl => bytecode.push(0x97),
1225            JvmInstruction::Dcmpg => bytecode.push(0x98),
1226
1227            JvmInstruction::Ifeq { target } => {
1228                jump_patches.push((pos, pos + 1, target.clone(), false));
1229                bytecode.push(0x99);
1230                bytecode.push(0);
1231                bytecode.push(0);
1232            }
1233            JvmInstruction::Ifne { target } => {
1234                jump_patches.push((pos, pos + 1, target.clone(), false));
1235                bytecode.push(0x9A);
1236                bytecode.push(0);
1237                bytecode.push(0);
1238            }
1239            JvmInstruction::Iflt { target } => {
1240                jump_patches.push((pos, pos + 1, target.clone(), false));
1241                bytecode.push(0x9B);
1242                bytecode.push(0);
1243                bytecode.push(0);
1244            }
1245            JvmInstruction::Ifge { target } => {
1246                jump_patches.push((pos, pos + 1, target.clone(), false));
1247                bytecode.push(0x9C);
1248                bytecode.push(0);
1249                bytecode.push(0);
1250            }
1251            JvmInstruction::Ifgt { target } => {
1252                jump_patches.push((pos, pos + 1, target.clone(), false));
1253                bytecode.push(0x9D);
1254                bytecode.push(0);
1255                bytecode.push(0);
1256            }
1257            JvmInstruction::Ifle { target } => {
1258                jump_patches.push((pos, pos + 1, target.clone(), false));
1259                bytecode.push(0x9E);
1260                bytecode.push(0);
1261                bytecode.push(0);
1262            }
1263            JvmInstruction::IfIcmpeq { target } => {
1264                jump_patches.push((pos, pos + 1, target.clone(), false));
1265                bytecode.push(0x9F);
1266                bytecode.push(0);
1267                bytecode.push(0);
1268            }
1269            JvmInstruction::IfIcmpne { target } => {
1270                jump_patches.push((pos, pos + 1, target.clone(), false));
1271                bytecode.push(0xA0);
1272                bytecode.push(0);
1273                bytecode.push(0);
1274            }
1275            JvmInstruction::IfIcmplt { target } => {
1276                jump_patches.push((pos, pos + 1, target.clone(), false));
1277                bytecode.push(0xA1);
1278                bytecode.push(0);
1279                bytecode.push(0);
1280            }
1281            JvmInstruction::IfIcmpge { target } => {
1282                jump_patches.push((pos, pos + 1, target.clone(), false));
1283                bytecode.push(0xA2);
1284                bytecode.push(0);
1285                bytecode.push(0);
1286            }
1287            JvmInstruction::IfIcmpgt { target } => {
1288                jump_patches.push((pos, pos + 1, target.clone(), false));
1289                bytecode.push(0xA3);
1290                bytecode.push(0);
1291                bytecode.push(0);
1292            }
1293            JvmInstruction::IfIcmple { target } => {
1294                jump_patches.push((pos, pos + 1, target.clone(), false));
1295                bytecode.push(0xA4);
1296                bytecode.push(0);
1297                bytecode.push(0);
1298            }
1299            JvmInstruction::IfAcmpeq { target } => {
1300                jump_patches.push((pos, pos + 1, target.clone(), false));
1301                bytecode.push(0xA5);
1302                bytecode.push(0);
1303                bytecode.push(0);
1304            }
1305            JvmInstruction::IfAcmpne { target } => {
1306                jump_patches.push((pos, pos + 1, target.clone(), false));
1307                bytecode.push(0xA6);
1308                bytecode.push(0);
1309                bytecode.push(0);
1310            }
1311            JvmInstruction::Ifnull { target } => {
1312                jump_patches.push((pos, pos + 1, target.clone(), false));
1313                bytecode.push(0xC6);
1314                bytecode.push(0);
1315                bytecode.push(0);
1316            }
1317            JvmInstruction::Ifnonnull { target } => {
1318                jump_patches.push((pos, pos + 1, target.clone(), false));
1319                bytecode.push(0xC7);
1320                bytecode.push(0);
1321                bytecode.push(0);
1322            }
1323            JvmInstruction::Goto { target } => {
1324                jump_patches.push((pos, pos + 1, target.clone(), false));
1325                bytecode.push(0xA7);
1326                bytecode.push(0);
1327                bytecode.push(0);
1328            }
1329            JvmInstruction::GotoW { target } => {
1330                jump_patches.push((pos, pos + 1, target.clone(), true));
1331                bytecode.push(0xC8);
1332                bytecode.push(0);
1333                bytecode.push(0);
1334                bytecode.push(0);
1335                bytecode.push(0);
1336            }
1337
1338            JvmInstruction::Return => bytecode.push(0xB1),
1339            JvmInstruction::Ireturn => bytecode.push(0xAC),
1340            JvmInstruction::Lreturn => bytecode.push(0xAD),
1341            JvmInstruction::Freturn => bytecode.push(0xAE),
1342            JvmInstruction::Dreturn => bytecode.push(0xAF),
1343            JvmInstruction::Areturn => bytecode.push(0xB0),
1344
1345            JvmInstruction::Arraylength => bytecode.push(0xBE),
1346            JvmInstruction::Athrow => bytecode.push(0xBF),
1347            JvmInstruction::Monitorenter => bytecode.push(0xC2),
1348            JvmInstruction::Monitorexit => bytecode.push(0xC3),
1349
1350            JvmInstruction::Iaload => bytecode.push(0x2E),
1351            JvmInstruction::Laload => bytecode.push(0x2F),
1352            JvmInstruction::Faload => bytecode.push(0x30),
1353            JvmInstruction::Daload => bytecode.push(0x31),
1354            JvmInstruction::Aaload => bytecode.push(0x32),
1355            JvmInstruction::Baload => bytecode.push(0x33),
1356            JvmInstruction::Saload => bytecode.push(0x34),
1357
1358            JvmInstruction::Iastore => bytecode.push(0x4F),
1359            JvmInstruction::Lastore => bytecode.push(0x50),
1360            JvmInstruction::Fastore => bytecode.push(0x51),
1361            JvmInstruction::Dastore => bytecode.push(0x52),
1362            JvmInstruction::Aastore => bytecode.push(0x53),
1363            JvmInstruction::Bastore => bytecode.push(0x54),
1364            JvmInstruction::Sastore => bytecode.push(0x55),
1365
1366            JvmInstruction::Getstatic { class_name, field_name, descriptor } => {
1367                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
1368                bytecode.push(0xB2); // getstatic
1369                bytecode.push((index >> 8) as u8);
1370                bytecode.push((index & 0xFF) as u8);
1371            }
1372            JvmInstruction::Putstatic { class_name, field_name, descriptor } => {
1373                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
1374                bytecode.push(0xB3); // putstatic
1375                bytecode.push((index >> 8) as u8);
1376                bytecode.push((index & 0xFF) as u8);
1377            }
1378            JvmInstruction::Getfield { class_name, field_name, descriptor } => {
1379                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
1380                bytecode.push(0xB4); // getfield
1381                bytecode.push((index >> 8) as u8);
1382                bytecode.push((index & 0xFF) as u8);
1383            }
1384            JvmInstruction::Putfield { class_name, field_name, descriptor } => {
1385                let index = self.add_field_ref(class_name.clone(), field_name.clone(), descriptor.clone());
1386                bytecode.push(0xB5); // putfield
1387                bytecode.push((index >> 8) as u8);
1388                bytecode.push((index & 0xFF) as u8);
1389            }
1390            JvmInstruction::Invokevirtual { class_name, method_name, descriptor } => {
1391                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
1392                bytecode.push(0xB6); // invokevirtual
1393                bytecode.push((index >> 8) as u8);
1394                bytecode.push((index & 0xFF) as u8);
1395            }
1396            JvmInstruction::Invokespecial { class_name, method_name, descriptor } => {
1397                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
1398                bytecode.push(0xB7); // invokespecial
1399                bytecode.push((index >> 8) as u8);
1400                bytecode.push((index & 0xFF) as u8);
1401            }
1402            JvmInstruction::Invokestatic { class_name, method_name, descriptor } => {
1403                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
1404                bytecode.push(0xB8); // invokestatic
1405                bytecode.push((index >> 8) as u8);
1406                bytecode.push((index & 0xFF) as u8);
1407            }
1408            JvmInstruction::Invokeinterface { class_name, method_name, descriptor } => {
1409                let index = self.add_interface_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
1410                bytecode.push(0xB9); // invokeinterface
1411                bytecode.push((index >> 8) as u8);
1412                bytecode.push((index & 0xFF) as u8);
1413
1414                // 计算参数数量(包括 this)
1415                let count = calculate_parameter_count(descriptor) + 1;
1416                bytecode.push(count as u8);
1417                bytecode.push(0);
1418            }
1419            JvmInstruction::Invokedynamic { class_name, method_name, descriptor } => {
1420                let index = self.add_method_ref(class_name.clone(), method_name.clone(), descriptor.clone());
1421                bytecode.push(0xBA); // invokedynamic
1422                bytecode.push((index >> 8) as u8);
1423                bytecode.push((index & 0xFF) as u8);
1424                bytecode.push(0);
1425                bytecode.push(0);
1426            }
1427            JvmInstruction::New { class_name } => {
1428                let index = self.add_class(class_name.clone());
1429                bytecode.push(0xBB); // new
1430                bytecode.push((index >> 8) as u8);
1431                bytecode.push((index & 0xFF) as u8);
1432            }
1433            JvmInstruction::Newarray { atype } => {
1434                bytecode.push(0xBC); // newarray
1435                bytecode.push(*atype);
1436            }
1437            JvmInstruction::Anewarray { class_name } => {
1438                let index = self.add_class(class_name.clone());
1439                bytecode.push(0xBD); // anewarray
1440                bytecode.push((index >> 8) as u8);
1441                bytecode.push((index & 0xFF) as u8);
1442            }
1443            JvmInstruction::Multianewarray { class_name, dimensions } => {
1444                let index = self.add_class(class_name.clone());
1445                bytecode.push(0xC5); // multianewarray
1446                bytecode.push((index >> 8) as u8);
1447                bytecode.push((index & 0xFF) as u8);
1448                bytecode.push(*dimensions);
1449            }
1450            JvmInstruction::Checkcast { class_name } => {
1451                let index = self.add_class(class_name.clone());
1452                bytecode.push(0xC0); // checkcast
1453                bytecode.push((index >> 8) as u8);
1454                bytecode.push((index & 0xFF) as u8);
1455            }
1456            JvmInstruction::Instanceof { class_name } => {
1457                let index = self.add_class(class_name.clone());
1458                bytecode.push(0xC1); // instanceof
1459                bytecode.push((index >> 8) as u8);
1460                bytecode.push((index & 0xFF) as u8);
1461            }
1462            JvmInstruction::Jsr { target } => {
1463                jump_patches.push((pos, pos + 1, target.clone(), false));
1464                bytecode.push(0xA8); // jsr
1465                bytecode.push(0);
1466                bytecode.push(0);
1467            }
1468            JvmInstruction::Ret { index } => {
1469                if *index <= 255 {
1470                    bytecode.push(0xA9); // ret
1471                    bytecode.push(*index as u8);
1472                }
1473                else {
1474                    bytecode.push(0xC4); // wide
1475                    bytecode.push(0xA9);
1476                    bytecode.push((*index >> 8) as u8);
1477                    bytecode.push((*index & 0xFF) as u8);
1478                }
1479            }
1480            JvmInstruction::Iinc { index, increment } => {
1481                if *index <= 255 && *increment >= -128 && *increment <= 127 {
1482                    bytecode.push(0x84); // iinc
1483                    bytecode.push(*index as u8);
1484                    bytecode.push(*increment as u8);
1485                }
1486                else {
1487                    bytecode.push(0xC4); // wide
1488                    bytecode.push(0x84);
1489                    bytecode.push((*index >> 8) as u8);
1490                    bytecode.push((*index & 0xFF) as u8);
1491                    bytecode.push((*increment >> 8) as u8);
1492                    bytecode.push((*increment & 0xFF) as u8);
1493                }
1494            }
1495            JvmInstruction::JsrW { target } => {
1496                jump_patches.push((pos, pos + 1, target.clone(), true));
1497                bytecode.push(0xC9); // jsr_w
1498                bytecode.push(0);
1499                bytecode.push(0);
1500                bytecode.push(0);
1501                bytecode.push(0);
1502            }
1503
1504            JvmInstruction::Lookupswitch { default, pairs } => {
1505                bytecode.push(0xAB); // lookupswitch
1506
1507                // 填充以对齐到 4 字节边界
1508                let padding = (4 - (bytecode.len() % 4)) % 4;
1509                for _ in 0..padding {
1510                    bytecode.push(0);
1511                }
1512
1513                // default 偏移量
1514                let default_patch_pos = bytecode.len();
1515                jump_patches.push((pos, default_patch_pos, default.clone(), true));
1516                bytecode.push(0);
1517                bytecode.push(0);
1518                bytecode.push(0);
1519                bytecode.push(0);
1520
1521                // npairs
1522                let npairs = pairs.len() as i32;
1523                bytecode.push((npairs >> 24) as u8);
1524                bytecode.push((npairs >> 16) as u8);
1525                bytecode.push((npairs >> 8) as u8);
1526                bytecode.push(npairs as u8);
1527
1528                // match-offset pairs
1529                for (val, target) in pairs {
1530                    // match
1531                    bytecode.push((val >> 24) as u8);
1532                    bytecode.push((val >> 16) as u8);
1533                    bytecode.push((val >> 8) as u8);
1534                    bytecode.push(*val as u8);
1535
1536                    // offset
1537                    let patch_pos = bytecode.len();
1538                    jump_patches.push((pos, patch_pos, target.clone(), true));
1539                    bytecode.push(0);
1540                    bytecode.push(0);
1541                    bytecode.push(0);
1542                    bytecode.push(0);
1543                }
1544            }
1545            JvmInstruction::Tableswitch { low, high, default, targets } => {
1546                bytecode.push(0xAA); // tableswitch
1547
1548                // 填充以对齐到 4 字节边界
1549                let padding = (4 - (bytecode.len() % 4)) % 4;
1550                for _ in 0..padding {
1551                    bytecode.push(0);
1552                }
1553
1554                // default 偏移量
1555                let default_patch_pos = bytecode.len();
1556                jump_patches.push((pos, default_patch_pos, default.clone(), true));
1557                bytecode.push(0);
1558                bytecode.push(0);
1559                bytecode.push(0);
1560                bytecode.push(0);
1561
1562                // low
1563                bytecode.push((low >> 24) as u8);
1564                bytecode.push((low >> 16) as u8);
1565                bytecode.push((low >> 8) as u8);
1566                bytecode.push(*low as u8);
1567
1568                // high
1569                bytecode.push((high >> 24) as u8);
1570                bytecode.push((high >> 16) as u8);
1571                bytecode.push((high >> 8) as u8);
1572                bytecode.push(*high as u8);
1573
1574                // offsets
1575                for target in targets {
1576                    let patch_pos = bytecode.len();
1577                    jump_patches.push((pos, patch_pos, target.clone(), true));
1578                    bytecode.push(0);
1579                    bytecode.push(0);
1580                    bytecode.push(0);
1581                    bytecode.push(0);
1582                }
1583            }
1584            JvmInstruction::Label { .. } => {}           // 已经在第一遍处理过
1585            JvmInstruction::Wide => bytecode.push(0xC4), // standalone wide is unusual but possible
1586        }
1587    }
1588}