jvm_assembler/formats/class/writer/
mod.rs

1//! JVM Class 文件写入器
2//!
3//! 这个模块实现了将 JVM 程序转换为 Class 文件字节码的功能。
4
5use crate::program::*;
6use byteorder::BigEndian;
7use gaia_types::{BinaryWriter, GaiaDiagnostics, Result};
8use std::io::Write;
9
10/// Class 文件写入器
11pub struct ClassWriter<W> {
12    /// 二进制汇编器
13    writer: BinaryWriter<W, BigEndian>,
14}
15
16impl<W> ClassWriter<W> {
17    /// 创建新的 Class 写入器
18    pub fn new(writer: W) -> Self {
19        Self { writer: BinaryWriter::new(writer) }
20    }
21
22    /// 完成写入并返回底层写入器
23    pub fn finish(self) -> W {
24        self.writer.finish()
25    }
26}
27
28impl<W: Write> ClassWriter<W> {
29    /// 将 ClassView 写入为二进制 Class 格式
30    pub fn write(mut self, program: &JvmProgram) -> GaiaDiagnostics<W> {
31        match self.write_class_file(program) {
32            Ok(_) => GaiaDiagnostics::success(self.finish()),
33            Err(error) => GaiaDiagnostics::failure(error),
34        }
35    }
36
37    /// 写入 Class 文件
38    fn write_class_file(&mut self, program: &JvmProgram) -> Result<()> {
39        // 写入魔数
40        self.writer.write_u32(0xCAFEBABE)?;
41        
42        // 写入版本信息
43        self.writer.write_u16(program.version.minor)?;
44        self.writer.write_u16(program.version.major)?;
45        
46        // 构建并写入常量池
47        self.write_constant_pool(program)?;
48        
49        // 写入访问标志
50        self.writer.write_u16(program.access_flags.to_flags())?;
51        
52        // 写入类索引(this_class)
53        self.writer.write_u16(2)?; // 类的 Class 条目在索引2
54        
55        // 写入超类索引(super_class)
56        if program.super_class.is_some() {
57            self.writer.write_u16(4)?; // 超类的 Class 条目在索引4
58        } else {
59            self.writer.write_u16(0)?;
60        }
61        
62        // 写入接口数量(暂时为0)
63        self.writer.write_u16(0)?;
64        
65        // 写入字段
66        self.write_fields(program)?;
67        
68        // 写入方法
69        self.write_methods(program)?;
70        
71        // 写入属性数量(暂时为0)
72        self.writer.write_u16(0)?;
73        
74        Ok(())
75    }
76    
77    /// 写入常量池
78    fn write_constant_pool(&mut self, program: &JvmProgram) -> Result<()> {
79        // 简化的常量池结构
80        let mut pool_entries = Vec::new();
81        
82        // 1. 类名的 UTF8 条目
83        pool_entries.push(format!("UTF8:{}", program.name));
84        
85        // 2. 类的 Class 条目(引用索引1)
86        pool_entries.push("CLASS:1".to_string());
87        
88        // 3. 超类名的 UTF8 条目
89        if let Some(super_class) = &program.super_class {
90            pool_entries.push(format!("UTF8:{}", super_class));
91        } else {
92            pool_entries.push("UTF8:java/lang/Object".to_string());
93        }
94        
95        // 4. 超类的 Class 条目(引用索引3)
96        pool_entries.push("CLASS:3".to_string());
97        
98        // 5. "Hello, World!" 字符串的 UTF8 条目
99        pool_entries.push("UTF8:Hello, World!".to_string());
100        
101        // 6. String 条目(引用索引5)
102        pool_entries.push("STRING:5".to_string());
103        
104        // 7. System 类名的 UTF8 条目
105        pool_entries.push("UTF8:java/lang/System".to_string());
106        
107        // 8. System 类的 Class 条目(引用索引7)
108        pool_entries.push("CLASS:7".to_string());
109        
110        // 9. out 字段名的 UTF8 条目
111        pool_entries.push("UTF8:out".to_string());
112        
113        // 10. PrintStream 类型描述符的 UTF8 条目
114        pool_entries.push("UTF8:Ljava/io/PrintStream;".to_string());
115        
116        // 11. NameAndType 条目(out 字段的名称和类型)
117        pool_entries.push("NAMEANDTYPE:9:10".to_string());
118        
119        // 12. Fieldref 条目(System.out)
120        pool_entries.push("FIELDREF:8:11".to_string());
121        
122        // 13. PrintStream 类名的 UTF8 条目
123        pool_entries.push("UTF8:java/io/PrintStream".to_string());
124        
125        // 14. PrintStream 类的 Class 条目(引用索引13)
126        pool_entries.push("CLASS:13".to_string());
127        
128        // 15. println 方法名的 UTF8 条目
129        pool_entries.push("UTF8:println".to_string());
130        
131        // 16. println 方法描述符的 UTF8 条目
132        pool_entries.push("UTF8:(Ljava/lang/String;)V".to_string());
133        
134        // 17. NameAndType 条目(println 方法的名称和描述符)
135        pool_entries.push("NAMEANDTYPE:15:16".to_string());
136        
137        // 18. Methodref 条目(PrintStream.println)
138        pool_entries.push("METHODREF:14:17".to_string());
139        
140        // 添加方法和字段的名称和描述符
141        for method in &program.methods {
142            pool_entries.push(format!("UTF8:{}", method.name));
143            pool_entries.push(format!("UTF8:{}", method.descriptor));
144        }
145        
146        for field in &program.fields {
147            pool_entries.push(format!("UTF8:{}", field.name));
148            pool_entries.push(format!("UTF8:{}", field.descriptor));
149        }
150        
151        // 添加 "Code" 属性名称
152        pool_entries.push("UTF8:Code".to_string());
153        
154        // 写入常量池计数(+1 因为索引从1开始)
155        self.writer.write_u16((pool_entries.len() + 1) as u16)?;
156        
157        // 写入常量池条目
158        for entry in &pool_entries {
159            if entry.starts_with("UTF8:") {
160                let utf8_str = &entry[5..];
161                self.writer.write_u8(1)?; // CONSTANT_Utf8 tag
162                self.writer.write_u16(utf8_str.len() as u16)?;
163                self.writer.write_all(utf8_str.as_bytes())?;
164            } else if entry.starts_with("CLASS:") {
165                let class_index: u16 = entry[6..].parse().unwrap();
166                self.writer.write_u8(7)?; // CONSTANT_Class tag
167                self.writer.write_u16(class_index)?;
168            } else if entry.starts_with("STRING:") {
169                let string_index: u16 = entry[7..].parse().unwrap();
170                self.writer.write_u8(8)?; // CONSTANT_String tag
171                self.writer.write_u16(string_index)?;
172            } else if entry.starts_with("NAMEANDTYPE:") {
173                let parts: Vec<&str> = entry[12..].split(':').collect();
174                let name_index: u16 = parts[0].parse().unwrap();
175                let descriptor_index: u16 = parts[1].parse().unwrap();
176                self.writer.write_u8(12)?; // CONSTANT_NameAndType tag
177                self.writer.write_u16(name_index)?;
178                self.writer.write_u16(descriptor_index)?;
179            } else if entry.starts_with("FIELDREF:") {
180                let parts: Vec<&str> = entry[9..].split(':').collect();
181                let class_index: u16 = parts[0].parse().unwrap();
182                let name_and_type_index: u16 = parts[1].parse().unwrap();
183                self.writer.write_u8(9)?; // CONSTANT_Fieldref tag
184                self.writer.write_u16(class_index)?;
185                self.writer.write_u16(name_and_type_index)?;
186            } else if entry.starts_with("METHODREF:") {
187                let parts: Vec<&str> = entry[10..].split(':').collect();
188                let class_index: u16 = parts[0].parse().unwrap();
189                let name_and_type_index: u16 = parts[1].parse().unwrap();
190                self.writer.write_u8(10)?; // CONSTANT_Methodref tag
191                self.writer.write_u16(class_index)?;
192                self.writer.write_u16(name_and_type_index)?;
193            }
194        }
195        
196        Ok(())
197    }
198    
199    /// 写入字段
200    fn write_fields(&mut self, program: &JvmProgram) -> Result<()> {
201        self.writer.write_u16(program.fields.len() as u16)?;
202        
203        for field in &program.fields {
204            self.writer.write_u16(field.access_flags.to_flags())?;
205            self.writer.write_u16(3)?; // 假设字段名在常量池索引3
206            self.writer.write_u16(4)?; // 假设字段描述符在常量池索引4
207            self.writer.write_u16(0)?; // 属性数量
208        }
209        
210        Ok(())
211    }
212    
213    /// 写入方法
214    fn write_methods(&mut self, program: &JvmProgram) -> Result<()> {
215        self.writer.write_u16(program.methods.len() as u16)?;
216        
217        for method in &program.methods {
218            self.writer.write_u16(method.access_flags.to_flags())?;
219            // 方法名和描述符在常量池中的索引需要根据实际位置计算
220            // 假设 main 方法名在索引19,描述符在索引20
221            self.writer.write_u16(19)?; // 方法名索引
222            self.writer.write_u16(20)?; // 方法描述符索引
223            
224            // 写入属性(Code 属性)
225            self.writer.write_u16(1)?; // 属性数量
226            self.write_code_attribute(method)?;
227        }
228        
229        Ok(())
230    }
231    
232    /// 写入 Code 属性
233    fn write_code_attribute(&mut self, method: &JvmMethod) -> Result<()> {
234        // Code 属性名称索引("Code" 在索引21)
235        self.writer.write_u16(21)?;
236        
237        let bytecode = self.generate_method_bytecode(method);
238        
239        // Code 属性长度(不包括属性名称索引和长度字段本身)
240        let attribute_length = 2 + 2 + 4 + bytecode.len() + 2 + 2;
241        self.writer.write_u32(attribute_length as u32)?;
242        
243        // max_stack 和 max_locals
244        self.writer.write_u16(2)?; // max_stack
245        self.writer.write_u16(1)?; // max_locals
246        
247        // 字节码长度和字节码
248        self.writer.write_u32(bytecode.len() as u32)?;
249        self.writer.write_all(&bytecode)?;
250        
251        // 异常表长度(0)
252        self.writer.write_u16(0)?;
253        
254        // 属性数量(0)
255        self.writer.write_u16(0)?;
256        
257        Ok(())
258    }
259    
260    /// 生成方法的字节码
261    fn generate_method_bytecode(&self, method: &JvmMethod) -> Vec<u8> {
262        let mut bytecode = Vec::new();
263        
264        for instruction in &method.instructions {
265            match instruction {
266                JvmInstruction::Nop => bytecode.push(0x00),
267                JvmInstruction::IconstM1 => bytecode.push(0x02),
268                JvmInstruction::Iconst0 => bytecode.push(0x03),
269                JvmInstruction::Iconst1 => bytecode.push(0x04),
270                JvmInstruction::Iconst2 => bytecode.push(0x05),
271                JvmInstruction::Iconst3 => bytecode.push(0x06),
272                JvmInstruction::Iconst4 => bytecode.push(0x07),
273                JvmInstruction::Iconst5 => bytecode.push(0x08),
274                JvmInstruction::Lconst0 => bytecode.push(0x09),
275                JvmInstruction::Lconst1 => bytecode.push(0x0A),
276                JvmInstruction::Fconst0 => bytecode.push(0x0B),
277                JvmInstruction::Fconst1 => bytecode.push(0x0C),
278                JvmInstruction::Fconst2 => bytecode.push(0x0D),
279                JvmInstruction::Dconst0 => bytecode.push(0x0E),
280                JvmInstruction::Dconst1 => bytecode.push(0x0F),
281                JvmInstruction::Ldc { symbol: _ } => {
282                    bytecode.push(0x12); // ldc
283                    bytecode.push(6); // String 常量在索引6
284                }
285                JvmInstruction::Iload0 => bytecode.push(0x1A),
286                JvmInstruction::Iload1 => bytecode.push(0x1B),
287                JvmInstruction::Iload2 => bytecode.push(0x1C),
288                JvmInstruction::Iload3 => bytecode.push(0x1D),
289                JvmInstruction::Aload0 => bytecode.push(0x2A),
290                JvmInstruction::Aload1 => bytecode.push(0x2B),
291                JvmInstruction::Aload2 => bytecode.push(0x2C),
292                JvmInstruction::Aload3 => bytecode.push(0x2D),
293                JvmInstruction::Istore0 => bytecode.push(0x3B),
294                JvmInstruction::Istore1 => bytecode.push(0x3C),
295                JvmInstruction::Istore2 => bytecode.push(0x3D),
296                JvmInstruction::Istore3 => bytecode.push(0x3E),
297                JvmInstruction::Astore0 => bytecode.push(0x4B),
298                JvmInstruction::Astore1 => bytecode.push(0x4C),
299                JvmInstruction::Astore2 => bytecode.push(0x4D),
300                JvmInstruction::Astore3 => bytecode.push(0x4E),
301                JvmInstruction::Iadd => bytecode.push(0x60),
302                JvmInstruction::Pop => bytecode.push(0x57),
303                JvmInstruction::Return => bytecode.push(0xB1),
304                JvmInstruction::Ireturn => bytecode.push(0xAC),
305                JvmInstruction::New { class_name: _ } => {
306                    bytecode.push(0xBB); // new
307                    bytecode.push(0x00); // 类索引高字节
308                    bytecode.push(0x02); // 类索引低字节
309                }
310
311                JvmInstruction::Getstatic { class_name: _, field_name: _, descriptor: _ } => {
312                    bytecode.push(0xB2); // getstatic
313                    bytecode.push(0x00); // 字段引用索引高字节
314                    bytecode.push(0x0C); // 字段引用索引低字节(System.out,索引12)
315                }
316                JvmInstruction::Invokevirtual { class_name: _, method_name: _, descriptor: _ } => {
317                    bytecode.push(0xB6); // invokevirtual
318                    bytecode.push(0x00); // 方法引用索引高字节
319                    bytecode.push(0x12); // 方法引用索引低字节(PrintStream.println,索引18)
320                }
321                _ => {
322                    // 对于其他指令,暂时使用 nop
323                    bytecode.push(0x00);
324                }
325            }
326        }
327        
328        // 如果方法没有指令,添加一个 return 指令
329        if bytecode.is_empty() {
330            bytecode.push(0xB1); // return
331        }
332        
333        bytecode
334    }
335}