Skip to content

Commit 430aaf9

Browse files
committed
Fixed some bytecode parsing and emitting bugs
1 parent 60c0cde commit 430aaf9

File tree

3 files changed

+90
-27
lines changed

3 files changed

+90
-27
lines changed

src/bytecode/classfile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ pub struct Annotation {
448448

449449
impl Annotation {
450450
pub fn len(&self) -> usize {
451-
self.element_value_pairs.iter().fold(2, |acc, x| acc + x.len())
451+
4 + self.element_value_pairs.len() * 2 + self.element_value_pairs.iter().fold(0, |acc, x| acc + x.len())
452452
}
453453
}
454454

src/bytecode/io/reader.rs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,22 @@ impl ClassReader {
309309
}
310310

311311
fn parse_code(len: usize, reader: &mut BlockReader) -> Vec<Instruction> {
312+
/*
312313
let read_bytes: Cell<usize> = Cell::new(0);
313314
314315
(0..len).take_while(|_| read_bytes.get() < len).map(|_| {
315316
let instruction = ClassReader::parse_instruction(reader, read_bytes.get());
316317
317318
read_bytes.set(read_bytes.get() + instruction.len());
318319
instruction
320+
}).collect()*/
321+
let read_bytes: Cell<usize> = Cell::new(0);
322+
323+
(0..len).take_while(|_| read_bytes.get() < len).map(|_| {
324+
let instruction = ClassReader::parse_instruction(reader, read_bytes.get());
325+
326+
read_bytes.set(reader.position());
327+
instruction
319328
}).collect()
320329
}
321330

@@ -836,28 +845,33 @@ impl ClassReader {
836845

837846
// TODO remove pub after testing
838847
pub struct BlockReader<'a> {
839-
source: &'a mut Read
848+
source: &'a mut Read,
849+
position: usize
840850
}
841851

842852
impl<'a> BlockReader<'a> {
843853

844854
pub fn new<T>(source: &'a mut T) -> BlockReader where T: Read {
845-
BlockReader { source: source }
855+
BlockReader { source: source, position: 0 }
846856
}
847857

848858
pub fn read_u64(&mut self) -> Result<u64, Error> {
849859
let mut buf: [u8; 8] = [0; 8];
850860

851861
match self.source.read_exact(&mut buf) {
852-
Ok(_) => Ok(
862+
Ok(_) => {
863+
self.position += 8;
864+
865+
Ok(
853866
((buf[0] as u64) << 56) +
854867
((buf[1] as u64) << 48) +
855868
((buf[2] as u64) << 40) +
856869
((buf[3] as u64) << 32) +
857870
((buf[4] as u64) << 24) +
858871
((buf[5] as u64) << 16) +
859872
((buf[6] as u64) << 8) +
860-
buf[7] as u64),
873+
buf[7] as u64)
874+
},
861875
Err(err) => Err(err)
862876
}
863877
}
@@ -871,11 +885,14 @@ impl<'a> BlockReader<'a> {
871885
let mut buf: [u8; 4] = [0; 4];
872886

873887
match self.source.read_exact(&mut buf) {
874-
Ok(_) => Ok(
888+
Ok(_) => {
889+
self.position += 4;
890+
Ok(
875891
((buf[0] as u32) << 24) +
876892
((buf[1] as u32) << 16) +
877893
((buf[2] as u32) << 8) +
878-
buf[3] as u32),
894+
buf[3] as u32)
895+
},
879896
Err(err) => Err(err)
880897
}
881898
}
@@ -889,7 +906,10 @@ impl<'a> BlockReader<'a> {
889906
let mut buf: [u8; 2] = [0; 2];
890907

891908
match self.source.read_exact(&mut buf) {
892-
Ok(_) => Ok(((buf[0] as u16) << 8) + buf[1] as u16),
909+
Ok(_) => {
910+
self.position += 2;
911+
Ok(((buf[0] as u16) << 8) + buf[1] as u16)
912+
},
893913
Err(err) => Err(err)
894914
}
895915
}
@@ -902,7 +922,10 @@ impl<'a> BlockReader<'a> {
902922
let mut buf: [u8; 1] = [0; 1];
903923

904924
match self.source.read_exact(&mut buf) {
905-
Ok(_) => Ok(buf[0]),
925+
Ok(_) => {
926+
self.position += 1;
927+
Ok(buf[0])
928+
},
906929
Err(err) => Err(err)
907930
}
908931
}
@@ -915,7 +938,10 @@ impl<'a> BlockReader<'a> {
915938
let mut tmp: Vec<u8> = Vec::with_capacity(count);
916939

917940
match self.source.take(count as u64).read_to_end(&mut tmp) {
918-
Ok(_) => Ok(tmp),
941+
Ok(_) => {
942+
self.position += count;
943+
Ok(tmp)
944+
},
919945
Err(err) => Err(err)
920946
}
921947
}
@@ -931,7 +957,10 @@ impl<'a> BlockReader<'a> {
931957
let mut tmp: Vec<u8> = vec![];
932958

933959
match self.source.read_to_end(&mut tmp) {
934-
Ok(_) => Ok(tmp),
960+
Ok(_) => {
961+
self.position += tmp.len();
962+
Ok(tmp)
963+
},
935964
Err(err) => Err(err)
936965
}
937966
}
@@ -943,6 +972,10 @@ impl<'a> BlockReader<'a> {
943972

944973
tmp
945974
}
975+
976+
pub fn position(&self) -> usize {
977+
self.position
978+
}
946979
}
947980

948981

src/bytecode/io/writer.rs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,25 @@ impl<'a> ClassWriter<'a> {
124124
&Attribute::RawAttribute { name_index: ref n_idx, info: ref bytes } => self.write_u16(n_idx.idx as u16).and(self.write_u32(bytes.len() as u32)).and(self.write_n(bytes)),
125125
&Attribute::ConstantValue(ref idx) => self.write_u16(cp.get_utf8_index("ConstantValue") as u16).and(self.write_u32(2)).and(self.write_u16(idx.idx as u16)),
126126
&Attribute::Code { max_stack, max_locals, ref code, ref exception_table, ref attributes } => {
127+
let mut target: Vec<u8> = vec![];
128+
129+
{
130+
let mut code_writer = ClassWriter::new(&mut target);
131+
132+
let _ = code_writer.write_u16(max_stack)
133+
.and(code_writer.write_u16(max_locals))
134+
.and(code_writer.write_instructions(code))
135+
.and(code_writer.write_exception_handlers(exception_table))
136+
.and(code_writer.write_attributes(attributes, cp));
137+
}
138+
127139
self.write_u16(cp.get_utf8_index("Code") as u16)
128-
.and(self.write_u32(33))
129-
.and(self.write_u16(max_stack))
130-
.and(self.write_u16(max_locals))
131-
.and(self.write_instructions(code))
132-
.and(self.write_exception_handlers(exception_table))
133-
.and(self.write_attributes(attributes, cp))
140+
.and(self.write_u32(target.len() as u32))
141+
.and(self.write_n(&target))
134142
},
135143
&Attribute::StackMapTable(ref table) => self.write_stack_map_table(table, cp),
136-
&Attribute::Exceptions(ref table) => self.write_u16(cp.get_utf8_index("Exceptions") as u16).and(self.write_u32(2 + (table.len() as u32) * 2)).and(table.iter().fold(Ok(0), |_, x| self.write_u16(x.idx as u16))),
137-
&Attribute::InnerClasses(ref table) => self.write_u16(cp.get_utf8_index("InnerClasses") as u16).and(self.write_u32(2 + (table.len() as u32) * 8)).and(table.iter().fold(Ok(0), |_, x| {
144+
&Attribute::Exceptions(ref table) => self.write_u16(cp.get_utf8_index("Exceptions") as u16).and(self.write_u32(2 + (table.len() as u32) * 2)).and(self.write_u16(table.len() as u16)).and(table.iter().fold(Ok(0), |_, x| self.write_u16(x.idx as u16))),
145+
&Attribute::InnerClasses(ref table) => self.write_u16(cp.get_utf8_index("InnerClasses") as u16).and(self.write_u32(2 + (table.len() as u32) * 8)).and(self.write_u16(table.len() as u16)).and(table.iter().fold(Ok(0), |_, x| {
138146
self.write_u16(x.inner_class_info_index.idx as u16)
139147
.and(self.write_u16(x.outer_class_info_index.idx as u16))
140148
.and(self.write_u16(x.inner_name_index.idx as u16))
@@ -163,8 +171,24 @@ impl<'a> ClassWriter<'a> {
163171
.and(self.write_u16(x.index))
164172
})),
165173
&Attribute::Deprecated => self.write_u16(cp.get_utf8_index("Deprecated") as u16).and(self.write_u32(0)),
166-
&Attribute::RuntimeVisibleAnnotations(ref table) => self.write_u16(cp.get_utf8_index("RuntimeVisibleAnnotations") as u16).and(self.write_u32(table.iter().fold(2, |acc, x| acc + x.len() as u32))).and(table.iter().fold(Ok(0), |_, x| self.write_annotation(x, cp))),
167-
&Attribute::RuntimeInvisibleAnnotations(ref table) => self.write_u16(cp.get_utf8_index("RuntimeInvisibleAnnotations") as u16).and(self.write_u32(table.iter().fold(2, |acc, x| acc + x.len() as u32))).and(table.iter().fold(Ok(0), |_, x| self.write_annotation(x, cp))),
174+
&Attribute::RuntimeVisibleAnnotations(ref table) => {
175+
self.write_u16(cp.get_utf8_index("RuntimeVisibleAnnotations") as u16)
176+
// attribute_length
177+
.and(self.write_u32(table.iter().fold(2, |acc, x| acc + x.len() as u32)))
178+
// num_annotations
179+
.and(self.write_u16(table.len() as u16))
180+
// annotations
181+
.and(table.iter().fold(Ok(0), |_, x| self.write_annotation(x, cp)))
182+
},
183+
&Attribute::RuntimeInvisibleAnnotations(ref table) => {
184+
self.write_u16(cp.get_utf8_index("RuntimeInvisibleAnnotations") as u16)
185+
// attribute_length
186+
.and(self.write_u32(table.iter().fold(2, |acc, x| acc + x.len() as u32)))
187+
// num_annotations
188+
.and(self.write_u16(table.len() as u16))
189+
// annotations
190+
.and(table.iter().fold(Ok(0), |_, x| self.write_annotation(x, cp)))
191+
},
168192
&Attribute::RuntimeVisibleParameterAnnotations(ref table) => {
169193
self.write_u16(cp.get_utf8_index("RuntimeVisibleParameterAnnotations") as u16)
170194
// attribute_length
@@ -185,11 +209,11 @@ impl<'a> ClassWriter<'a> {
185209
},
186210
&Attribute::RuntimeVisibleTypeAnnotations(ref table) => {
187211
// TODO
188-
self.write_u8(1)
212+
self.write_u32(1)
189213
},
190214
&Attribute::RuntimeInvisibleTypeAnnotations(ref table) => {
191215
// TODO
192-
self.write_u8(2)
216+
self.write_u16(2)
193217
},
194218
&Attribute::AnnotationDefault(ref value) => {
195219
self.write_u16(cp.get_utf8_index("AnnotationDefault") as u16)
@@ -282,7 +306,12 @@ impl<'a> ClassWriter<'a> {
282306
}
283307

284308
fn write_annotation(&mut self, annotation: &Annotation, cp: &ConstantPool) -> Result<usize, Error> {
285-
self.write_u16(annotation.type_index.idx as u16).and(annotation.element_value_pairs.iter().fold(Ok(0), |_, x| self.write_element_value_pair(x, cp)))
309+
// type_index
310+
self.write_u16(annotation.type_index.idx as u16)
311+
// num_element_value_pairs
312+
.and(self.write_u16(annotation.element_value_pairs.len() as u16))
313+
// element_value_pairs
314+
.and(annotation.element_value_pairs.iter().fold(Ok(0), |_, x| self.write_element_value_pair(x, cp)))
286315
}
287316

288317
fn write_instructions(&mut self, instructions: &Vec<Instruction>) -> Result<usize, Error> {
@@ -295,7 +324,7 @@ impl<'a> ClassWriter<'a> {
295324
})
296325
};
297326

298-
self.write_u32(written_bytes as u32).and_then(|x| self.write_n(&target).map(|y| x + y))
327+
self.write_u32(target.len() as u32).and_then(|x| self.write_n(&target).map(|y| x + y))
299328
}
300329

301330
/// Renders a single instruction into the output stream
@@ -304,6 +333,7 @@ impl<'a> ClassWriter<'a> {
304333
&Instruction::AALOAD => self.write_u8(0x32),
305334
&Instruction::AASTORE => self.write_u8(0x53),
306335
&Instruction::ACONST_NULL => self.write_u8(0x01),
336+
&Instruction::ALOAD(value) => self.write_u8(0x19).and(self.write_u8(value)),
307337
&Instruction::ALOAD_0 => self.write_u8(0x2a),
308338
&Instruction::ALOAD_1 => self.write_u8(0x2b),
309339
&Instruction::ALOAD_2 => self.write_u8(0x2c),
@@ -429,8 +459,8 @@ impl<'a> ClassWriter<'a> {
429459
&Instruction::IMUL => self.write_u8(0x68),
430460
&Instruction::INEG => self.write_u8(0x74),
431461
&Instruction::INSTANCEOF(value) => self.write_u8(0xc1).and(self.write_u16(value)),
432-
&Instruction::INVOKEDYNAMIC(value) => self.write_u8(0xba).and(self.write_u16(value)),
433-
&Instruction::INVOKEINTERFACE(a, b) => self.write_u8(0xb9).and(self.write_u16(a)).and(self.write_u8(b)),
462+
&Instruction::INVOKEDYNAMIC(value) => self.write_u8(0xba).and(self.write_u16(value)).and(self.write_u16(0)),
463+
&Instruction::INVOKEINTERFACE(a, b) => self.write_u8(0xb9).and(self.write_u16(a)).and(self.write_u8(b)).and(self.write_u8(0)),
434464
&Instruction::INVOKESPECIAL(value) => self.write_u8(0xb7).and(self.write_u16(value)),
435465
&Instruction::INVOKESTATIC(value) => self.write_u8(0xb8).and(self.write_u16(value)),
436466
&Instruction::INVOKEVIRTUAL(value) => self.write_u8(0xb6).and(self.write_u16(value)),

0 commit comments

Comments
 (0)