Skip to content

Commit 5435b91

Browse files
Merge pull request #5 from jbalint/WIP
Many improvements
2 parents 2c2c678 + 78efecf commit 5435b91

18 files changed

+1035
-504
lines changed

Cargo.lock

Lines changed: 206 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,10 @@ version = "0.1.0"
44
authors = ["Christopher Wells <[email protected]>"]
55

66
[dependencies]
7+
8+
[dev-dependencies]
9+
insta = "1.3.0"
10+
11+
[[bin]]
12+
name = "javap"
13+
path = "src/main.rs"

src/attribute.rs

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,87 @@
1-
use std::io;
1+
use std::{convert::TryInto, io};
22

33
use bytecode::*;
4-
use ::{parsing, ConstantPoolIndex};
4+
5+
use crate::ClassFile;
6+
use {parsing, ConstantPoolIndex};
57

68
const EXCEPTION_ENTRY_LENGTH: usize = 8;
79

8-
#[derive(Debug)]
9-
#[derive(Eq)]
10-
#[derive(PartialEq)]
10+
#[derive(Debug, Eq, PartialEq, Clone)]
1111
pub struct Attribute {
1212
pub attribute_name_index: ConstantPoolIndex,
1313
pub info: Vec<u8>,
1414
}
1515

16-
#[derive(Debug)]
17-
#[derive(PartialEq)]
16+
#[derive(Debug, Eq, PartialEq, Clone)]
17+
pub struct AttributeSet {
18+
pub attributes: Vec<Attribute>,
19+
}
20+
21+
impl AttributeSet {
22+
/// Find an attribute with the specified name
23+
pub fn find_attribute<T: AsRef<str>>(
24+
&self,
25+
class_file: &ClassFile,
26+
attribute_name: T,
27+
) -> Option<&Attribute> {
28+
// we can index this more efficiently
29+
self.attributes.iter().find(|attr| {
30+
class_file.get_constant_utf8(attr.attribute_name_index) == attribute_name.as_ref()
31+
})
32+
}
33+
34+
pub fn get_signature(&self, class_file: &ClassFile) -> Option<String> {
35+
self.find_attribute(class_file, "Signature").map(|attr| {
36+
// why is this such a PITA
37+
let boxed_slice = attr.info.clone().into_boxed_slice();
38+
let boxed_array: Box<[u8; 2]> = match boxed_slice.try_into() {
39+
Ok(ba) => ba,
40+
Err(o) => panic!("Expected a Vec of length {} but it was {}", 2, o.len()),
41+
};
42+
let index = u16::from_be_bytes(*boxed_array);
43+
44+
class_file.get_constant_utf8(index as usize).to_string()
45+
})
46+
}
47+
}
48+
49+
#[derive(Debug, PartialEq)]
1850
pub struct Code {
1951
pub max_stack: u16,
2052
pub max_locals: u16,
2153
pub code: Vec<(usize, Bytecode)>,
2254
pub exception_table: Vec<ExceptionTableEntry>,
23-
pub attributes: Vec<Attribute>,
55+
pub attributes: AttributeSet,
2456
}
2557

2658
impl Code {
2759
pub fn from_bytes(bytes: &[u8]) -> io::Result<Code> {
2860
let max_stack = u16::from_be_bytes([bytes[0], bytes[1]]);
2961
let max_locals = u16::from_be_bytes([bytes[2], bytes[3]]);
3062

31-
let code_length = u32::from_be_bytes(
32-
[bytes[4], bytes[5], bytes[6], bytes[7]]
33-
) as usize;
63+
let code_length = u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as usize;
3464

3565
let code_start = 8;
3666
let code_end = code_start + code_length;
3767
let code_bytes = &bytes[code_start..code_end];
3868

3969
let code = Bytecode::from_bytes(code_bytes);
4070

41-
let exception_table_length = u16::from_be_bytes(
42-
[bytes[code_end], bytes[code_end + 1]]
43-
) as usize;
71+
let exception_table_length =
72+
u16::from_be_bytes([bytes[code_end], bytes[code_end + 1]]) as usize;
4473

4574
let mut exception_table = Vec::with_capacity(exception_table_length);
4675
for i in 0..exception_table_length {
4776
let entry_start = (code_end + 2) + i * EXCEPTION_ENTRY_LENGTH;
4877
let entry_end = entry_start + EXCEPTION_ENTRY_LENGTH;
4978

50-
let entry = ExceptionTableEntry::from_bytes(
51-
&bytes[entry_start..entry_end]
52-
);
79+
let entry = ExceptionTableEntry::from_bytes(&bytes[entry_start..entry_end]);
5380

5481
exception_table.push(entry);
5582
}
5683

57-
let attributes_start = (code_end + 2) +
58-
exception_table_length * EXCEPTION_ENTRY_LENGTH;
84+
let attributes_start = (code_end + 2) + exception_table_length * EXCEPTION_ENTRY_LENGTH;
5985

6086
let mut attribute_bytes = &bytes[attributes_start..];
6187
let attributes = parsing::read_attributes(&mut attribute_bytes)?;
@@ -70,8 +96,7 @@ impl Code {
7096
}
7197
}
7298

73-
#[derive(Debug)]
74-
#[derive(PartialEq)]
99+
#[derive(Debug, PartialEq)]
75100
pub struct ExceptionTableEntry {
76101
pub start_pc: u16,
77102
pub end_pc: u16,

0 commit comments

Comments
 (0)