1#[derive(Debug, Clone)]
4pub enum JvmInstruction {
5 Ldc(u16), Ldc2W(u16), IconstM1, Iconst0, Iconst1, Iconst2, Iconst3, Iconst4, Iconst5, Lconst0, Lconst1, Bipush(i8), Sipush(i16), Pop, Dup, Swap, Iadd, Isub, Imul, Idiv, Irem, Dadd, Dsub, Dmul, Ddiv, I2d, D2i, Ifeq(u16), Ifne(u16), Iflt(u16), Ifge(u16), Ifgt(u16), Ifle(u16), Goto(u16), Iload(u8), Iload0, Iload1, Iload2, Iload3, Istore(u8), Istore0, Istore1, Istore2, Istore3, Aload(u8), Aload0, Aload1, Aload2, Aload3, Astore(u8), Astore0, Astore1, Astore2, Astore3, Dload(u8), Dload0, Dload1, Dload2, Dload3, Dstore(u8), Dstore0, Dstore1, Dstore2, Dstore3, Lload(u8), Lload0, Lload1, Lload2, Lload3, Lstore(u8), Lstore0, Lstore1, Lstore2, Lstore3, Invokevirtual(u16), Invokestatic(u16), Invokespecial(u16), Invokedynamic(u16), New(u16), Return, Ireturn, Getstatic(u16), Dconst0, Dconst1, Nop, }
119
120#[derive(Debug, Clone)]
122pub enum ConstantPoolEntry {
123 Utf8(String),
124 Class(u16),
125 String(u16),
126 Fieldref(u16, u16),
127 Methodref(u16, u16),
128 NameAndType(u16, u16),
129 Integer(i32),
130 Float(f32),
131 Long(i64),
132 Double(f64),
133 Placeholder, }
135
136#[derive(Debug, Clone)]
138pub enum ConstantPoolError {
139 SizeLimitExceeded(u16),
140}
141
142#[derive(Debug, Clone)]
144pub struct ConstantPool {
145 entries: Vec<ConstantPoolEntry>,
146}
147
148impl Default for ConstantPool {
149 fn default() -> Self {
150 Self::new()
151 }
152}
153
154impl ConstantPool {
155 pub fn new() -> Self {
156 Self {
157 entries: Vec::new(),
158 }
159 }
160
161 pub fn add_utf8(&mut self, value: String) -> Result<u16, String> {
162 let index = self.entries.len();
163 if index >= u16::MAX as usize {
164 return Err(format!(
165 "Constant pool size exceeds the maximum limit of {}",
166 u16::MAX
167 ));
168 }
169 self.entries.push(ConstantPoolEntry::Utf8(value));
170 Ok(index as u16 + 1)
171 }
172
173 pub fn add_class(&mut self, name_index: u16) -> Result<u16, String> {
174 let index = self.entries.len();
175 if index >= u16::MAX as usize {
176 return Err(format!(
177 "Constant pool size exceeds the maximum limit of {}",
178 u16::MAX
179 ));
180 }
181 self.entries.push(ConstantPoolEntry::Class(name_index));
182 Ok(index as u16 + 1)
183 }
184
185 pub fn add_string(&mut self, utf8_index: u16) -> Result<u16, String> {
186 let index = self.entries.len();
187 if index >= u16::MAX as usize {
188 return Err(format!(
189 "Constant pool size exceeds the maximum limit of {}",
190 u16::MAX
191 ));
192 }
193 self.entries.push(ConstantPoolEntry::String(utf8_index));
194 Ok(index as u16 + 1)
195 }
196
197 pub fn add_fieldref(
198 &mut self,
199 class_index: u16,
200 name_and_type_index: u16,
201 ) -> Result<u16, String> {
202 let index = self.entries.len();
203 if index >= u16::MAX as usize {
204 return Err(format!(
205 "Constant pool size exceeds the maximum limit of {}",
206 u16::MAX
207 ));
208 }
209 self.entries.push(ConstantPoolEntry::Fieldref(
210 class_index,
211 name_and_type_index,
212 ));
213 Ok(index as u16 + 1)
214 }
215
216 pub fn add_methodref(
217 &mut self,
218 class_index: u16,
219 name_and_type_index: u16,
220 ) -> Result<u16, String> {
221 let index = self.entries.len();
222 if index >= u16::MAX as usize {
223 return Err(format!(
224 "Constant pool size exceeds the maximum limit of {}",
225 u16::MAX
226 ));
227 }
228 self.entries.push(ConstantPoolEntry::Methodref(
229 class_index,
230 name_and_type_index,
231 ));
232 Ok(index as u16 + 1)
233 }
234
235 pub fn add_name_and_type(
236 &mut self,
237 name_index: u16,
238 descriptor_index: u16,
239 ) -> Result<u16, String> {
240 let index = self.entries.len();
241 if index >= u16::MAX as usize {
242 return Err(format!(
243 "Constant pool size exceeds the maximum limit of {}",
244 u16::MAX
245 ));
246 }
247 self.entries
248 .push(ConstantPoolEntry::NameAndType(name_index, descriptor_index));
249 Ok(index as u16 + 1)
250 }
251
252 pub fn add_integer(&mut self, value: i32) -> Result<u16, String> {
253 let index = self.entries.len();
254 if index >= u16::MAX as usize {
255 return Err(format!(
256 "Constant pool size exceeds the maximum limit of {}",
257 u16::MAX
258 ));
259 }
260 self.entries.push(ConstantPoolEntry::Integer(value));
261 Ok(index as u16 + 1)
262 }
263
264 pub fn add_float(&mut self, value: f32) -> Result<u16, String> {
265 let index = self.entries.len();
266 if index >= u16::MAX as usize {
267 return Err(format!(
268 "Constant pool size exceeds the maximum limit of {}",
269 u16::MAX
270 ));
271 }
272 self.entries.push(ConstantPoolEntry::Float(value));
273 Ok(index as u16 + 1)
274 }
275
276 pub fn add_long(&mut self, value: i64) -> Result<u16, String> {
277 let index = self.entries.len();
278 if index + 1 >= u16::MAX as usize {
279 return Err(format!(
280 "Constant pool size exceeds the maximum limit of {} (long requires 2 slots)",
281 u16::MAX
282 ));
283 }
284 self.entries.push(ConstantPoolEntry::Long(value));
285 self.entries.push(ConstantPoolEntry::Placeholder);
287 Ok(index as u16 + 1)
288 }
289
290 pub fn add_double(&mut self, value: f64) -> Result<u16, String> {
291 let index = self.entries.len();
292 if index + 1 >= u16::MAX as usize {
293 return Err(format!(
294 "Constant pool size exceeds the maximum limit of {} (double requires 2 slots)",
295 u16::MAX
296 ));
297 }
298 self.entries.push(ConstantPoolEntry::Double(value));
299 self.entries.push(ConstantPoolEntry::Placeholder);
301 Ok(index as u16 + 1)
302 }
303
304 pub fn add_placeholder(&mut self) -> Result<u16, String> {
305 let index = self.entries.len();
306 if index >= u16::MAX as usize {
307 return Err(format!(
308 "Constant pool size exceeds the maximum limit of {}",
309 u16::MAX
310 ));
311 }
312 self.entries.push(ConstantPoolEntry::Placeholder);
313 Ok(index as u16 + 1)
314 }
315
316 pub fn entries(&self) -> &Vec<ConstantPoolEntry> {
317 &self.entries
318 }
319}