jvm_assembler/formats/class/writer/
pool.rs1use super::{ClassWriter, CpEntry};
2use std::io::Write;
3
4impl<W: Write> ClassWriter<W> {
5 pub fn add_utf8(&mut self, s: String) -> u16 {
7 self.add_cp_entry(CpEntry::Utf8(s))
8 }
9
10 pub fn add_class(&mut self, name: String) -> u16 {
12 let name_index = self.add_utf8(name);
13 self.add_cp_entry(CpEntry::Class(name_index))
14 }
15
16 pub fn add_string(&mut self, value: String) -> u16 {
18 let utf8_index = self.add_utf8(value);
19 self.add_cp_entry(CpEntry::String(utf8_index))
20 }
21
22 pub fn add_name_and_type(&mut self, name: String, descriptor: String) -> u16 {
24 let name_index = self.add_utf8(name);
25 let descriptor_index = self.add_utf8(descriptor);
26 self.add_cp_entry(CpEntry::NameAndType(name_index, descriptor_index))
27 }
28
29 pub fn add_field_ref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
31 let class_index = self.add_class(class_name);
32 let name_and_type_index = self.add_name_and_type(name, descriptor);
33 self.add_cp_entry(CpEntry::Fieldref(class_index, name_and_type_index))
34 }
35
36 pub fn add_method_ref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
38 let class_index = self.add_class(class_name);
39 let name_and_type_index = self.add_name_and_type(name, descriptor);
40 self.add_cp_entry(CpEntry::Methodref(class_index, name_and_type_index))
41 }
42
43 pub fn add_interface_method_ref(&mut self, class_name: String, name: String, descriptor: String) -> u16 {
45 let class_index = self.add_class(class_name);
46 let name_and_type_index = self.add_name_and_type(name, descriptor);
47 self.add_cp_entry(CpEntry::InterfaceMethodref(class_index, name_and_type_index))
48 }
49
50 pub fn add_int(&mut self, val: i32) -> u16 {
52 self.add_cp_entry(CpEntry::Integer(val))
53 }
54
55 pub fn add_float(&mut self, val: f32) -> u16 {
57 self.add_cp_entry(CpEntry::Float(val.to_bits()))
58 }
59
60 pub fn add_long(&mut self, val: i64) -> u16 {
62 self.add_cp_entry(CpEntry::Long(val))
63 }
64
65 pub fn add_double(&mut self, val: f64) -> u16 {
67 self.add_cp_entry(CpEntry::Double(val.to_bits()))
68 }
69
70 pub fn add_cp_entry(&mut self, entry: CpEntry) -> u16 {
72 if let Some(&index) = self.cp_map.get(&entry) {
73 return index;
74 }
75
76 let index = (self.cp_entries.len() + 1) as u16;
77 self.cp_entries.push(entry.clone());
78 self.cp_map.insert(entry, index);
79
80 match self.cp_entries.last().unwrap() {
82 CpEntry::Long(_) | CpEntry::Double(_) => {
83 self.cp_entries.push(CpEntry::Utf8("Padding".to_string()));
85 }
86 _ => {}
87 }
88
89 index
90 }
91
92 pub fn write_constant_pool(&mut self) -> gaia_types::Result<()> {
94 self.writer.write_u16((self.cp_entries.len() + 1) as u16)?;
96
97 let mut i = 0;
99 while i < self.cp_entries.len() {
100 let entry = &self.cp_entries[i];
101 match entry {
102 CpEntry::Utf8(s) => {
103 self.writer.write_u8(1)?; self.writer.write_u16(s.len() as u16)?;
105 self.writer.write_all(s.as_bytes())?;
106 }
107 CpEntry::Class(name_idx) => {
108 self.writer.write_u8(7)?; self.writer.write_u16(*name_idx)?;
110 }
111 CpEntry::String(utf8_idx) => {
112 self.writer.write_u8(8)?; self.writer.write_u16(*utf8_idx)?;
114 }
115 CpEntry::NameAndType(name_idx, desc_idx) => {
116 self.writer.write_u8(12)?; self.writer.write_u16(*name_idx)?;
118 self.writer.write_u16(*desc_idx)?;
119 }
120 CpEntry::Fieldref(class_idx, nt_idx) => {
121 self.writer.write_u8(9)?; self.writer.write_u16(*class_idx)?;
123 self.writer.write_u16(*nt_idx)?;
124 }
125 CpEntry::Methodref(class_idx, nt_idx) => {
126 self.writer.write_u8(10)?; self.writer.write_u16(*class_idx)?;
128 self.writer.write_u16(*nt_idx)?;
129 }
130 CpEntry::InterfaceMethodref(class_idx, nt_idx) => {
131 self.writer.write_u8(11)?; self.writer.write_u16(*class_idx)?;
133 self.writer.write_u16(*nt_idx)?;
134 }
135 CpEntry::Integer(val) => {
136 self.writer.write_u8(3)?; self.writer.write_i32(*val)?;
138 }
139 CpEntry::Float(bits) => {
140 self.writer.write_u8(4)?; self.writer.write_u32(*bits)?;
142 }
143 CpEntry::Long(val) => {
144 self.writer.write_u8(5)?; self.writer.write_i64(*val)?;
146 i += 1; }
148 CpEntry::Double(bits) => {
149 self.writer.write_u8(6)?; self.writer.write_u64(*bits)?;
151 i += 1; }
153 }
154 i += 1;
155 }
156
157 Ok(())
158 }
159}