diff --git a/src/arm64.rs b/src/arm64.rs index 418e0fe..96e03ae 100644 --- a/src/arm64.rs +++ b/src/arm64.rs @@ -7,7 +7,7 @@ pub fn mask(len: u64, start: u64) -> u64 { /// Split a u64 into two chunks of high and low bits. pub fn split(x: u64) -> (u32, u32) { - ((x >> 16) as u32, (x as u64 & mask(16, 0)) as u32) + return ((x >> 16) as u32, (x & mask(16, 0)) as u32) } #[cfg(test)] @@ -19,7 +19,7 @@ mod tests { // an ARM64 instruction. // This is useful when loading immediates that don't fit the fixed // size instruction width of 32-bits. - let x = 0x48f0d0 as i32; + let x = 0x48f0d0i32; // To read x in x0 we can use a movz movk pair // movz x0, #0xf0d0 // movk x0, #0x48, lsl #16 @@ -28,11 +28,11 @@ mod tests { let hi = x as u64 >> 16; assert_eq!((hi << 16 | lo) as i32, x); // Another example with an even bigger integer - let v = 0x1122334455667788 as u64; - let lo_1 = v & mask(16, 0) as u64; - let lo_2 = v & mask(16, 16) as u64; - let lo_3 = v & mask(16, 32) as u64; - let lo_4 = v & mask(16, 48) as u64; + let v = 0x1122334455667788u64; + let lo_1 = v & mask(16, 0); + let lo_2 = v & mask(16, 16); + let lo_3 = v & mask(16, 32); + let lo_4 = v & mask(16, 48); assert_eq!(lo_4 | lo_3 | lo_2 | lo_1, v); } } diff --git a/src/jit.rs b/src/jit.rs index f15cddc..5f3e1cb 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -466,7 +466,7 @@ impl JitCache { self.registers.push_back(reg) } - match (dst.clone(), op2, dst) { + match (dst, op2, dst) { ( Operand::Register(r1), Operand::Register(r2), @@ -511,7 +511,7 @@ mod tests { use std::slice; - use crate::arm64::{self, mask}; + use crate::arm64::{self}; use super::*; use dynasmrt::dynasm; @@ -534,7 +534,7 @@ mod tests { ); epilogue!(ops); *buffer = ops.finalize().unwrap(); - return start; + return start } fn build_test_fn_x86( @@ -550,7 +550,7 @@ mod tests { ); let _offset = builder.as_ref().expect("REASON").offset(); *buffer = builder.expect("REASON").finalize().unwrap(); - return dynasmrt::AssemblyOffset(0); + return dynasmrt::AssemblyOffset(0) } fn build_test_fn_imm( @@ -558,12 +558,12 @@ mod tests { ) -> dynasmrt::AssemblyOffset { let mut builder = dynasmrt::x64::Assembler::new(); let mut litpool = LitPool::new(); - let offset = litpool.push_u64(0xcafebabe); + let _offset = litpool.push_u64(0xcafebabe); let a = 0xcafebabe; - let b = 0x0; + let _b = 0x0; use arm64; - use dynasmrt::DynasmLabelApi; + // let lo = a & mask(16, 0); let (hi, lo) = arm64::split(a); @@ -573,8 +573,8 @@ mod tests { println!("{:#x}", hi); dynasm!(builder.as_mut().expect("REASON") - ; movz x0, lo as u32 - ; movk x0, hi as u32, LSL #16 + ; movz x0, lo + ; movk x0, hi, LSL #16 ; movz x1, #0 ; add x0, x0, x1 ; ret @@ -582,7 +582,7 @@ mod tests { litpool.emit(builder.as_mut().unwrap()); let _offset = builder.as_ref().expect("REASON").offset(); *buffer = builder.expect("REASON").finalize().unwrap(); - return dynasmrt::AssemblyOffset(0); + return dynasmrt::AssemblyOffset(0) } fn build_test_fn_aarch64( @@ -609,7 +609,7 @@ mod tests { .expect("expected valid reference to builder") .offset(); *buffer = builder.expect("expected builder").finalize().unwrap(); - return dynasmrt::AssemblyOffset(0); + return dynasmrt::AssemblyOffset(0) } #[ignore = "ignore until unsafe segfault bug is fixed"] @@ -671,7 +671,7 @@ mod tests { assert!(class_file.is_ok()); let program = Program::new(&class_file.unwrap()); let mut runtime = Runtime::new(program); - assert!(runtime.run().is_ok()); + runtime.run().unwrap(); assert_eq!(runtime.top_return_value(), Some(Value::Int(55))); let trace = runtime.recorder.recording(); let mut jit = JitCache::new(); @@ -704,8 +704,8 @@ mod tests { let mut my_struct = MyStruct { registers: [0; 8] }; - let mut my_vec = MyVecStruct { - registers: vec![0 as u64; 8], + let _my_vec = MyVecStruct { + registers: vec![0u64; 8], }; unsafe { @@ -729,7 +729,7 @@ mod tests { inout(reg) &mut my_struct.registers => _, // inout(reg) my_vec.registers.as_mut_ptr() as *mut u64 => _, ); - } + }; // Now, my_struct.registers contains [1, 2, 3, 4, 5, 6, 7, 8] println!("{:?}", my_struct.registers); diff --git a/src/runtime.rs b/src/runtime.rs index 25413b8..4641345 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -216,10 +216,7 @@ impl Instruction { /// Returns the nth parameter of an instruction. pub fn nth(&self, index: usize) -> Option { match &self.operands { - Some(params) => match params.get(index) { - Some(v) => Some(*v), - _ => None, - }, + Some(params) => params.get(index).map(|v| return *v), None => None, } } @@ -231,7 +228,7 @@ impl Instruction { // Returns a copy of instruction parameters. pub fn get_params(&self) -> Option> { - return self.operands.clone(); + return self.operands.clone() } } @@ -429,25 +426,70 @@ impl Runtime { fn eval(&mut self, inst: &Instruction) -> Result<(), RuntimeError> { if let Some(_frame) = self.frames.last_mut() { match inst.mnemonic { - OPCode::IconstM1 => Ok(self.push(Value::Int(-1))), - OPCode::Iconst0 => Ok(self.push(Value::Int(0))), - OPCode::Iconst1 => Ok(self.push(Value::Int(1))), - OPCode::Iconst2 => Ok(self.push(Value::Int(2))), - OPCode::Iconst3 => Ok(self.push(Value::Int(3))), - OPCode::Iconst4 => Ok(self.push(Value::Int(4))), - OPCode::Iconst5 => Ok(self.push(Value::Int(5))), - OPCode::Lconst0 => Ok(self.push(Value::Long(0))), - OPCode::Lconst1 => Ok(self.push(Value::Long(1))), - OPCode::Fconst0 => Ok(self.push(Value::Float(0.))), - OPCode::Fconst1 => Ok(self.push(Value::Float(1.))), - OPCode::Fconst2 => Ok(self.push(Value::Float(2.))), - OPCode::Dconst0 => Ok(self.push(Value::Double(0.))), - OPCode::Dconst1 => Ok(self.push(Value::Double(1.))), + OPCode::IconstM1 => { + self.push(Value::Int(-1)); + return Ok(()) + }, + OPCode::Iconst0 => { + self.push(Value::Int(0)); + return Ok(()) + }, + OPCode::Iconst1 => { + self.push(Value::Int(1)); + return Ok(()) + }, + OPCode::Iconst2 => { + self.push(Value::Int(2)); + return Ok(()) + }, + OPCode::Iconst3 => { + self.push(Value::Int(3)); + return Ok(()) + }, + OPCode::Iconst4 => { + self.push(Value::Int(4)); + return Ok(()) + }, + OPCode::Iconst5 => { + self.push(Value::Int(5)); + return Ok(()) + }, + OPCode::Lconst0 => { + self.push(Value::Long(0)); + return Ok(()) + }, + OPCode::Lconst1 => { + self.push(Value::Long(1)); + return Ok(()) + }, + OPCode::Fconst0 => { + self.push(Value::Float(0.)); + return Ok(()) + }, + OPCode::Fconst1 => { + self.push(Value::Float(1.)); + return Ok(()) + }, + OPCode::Fconst2 => { + self.push(Value::Float(2.)); + return Ok(()) + }, + OPCode::Dconst0 => { + self.push(Value::Double(0.)); + return Ok(()) + }, + OPCode::Dconst1 => { + self.push(Value::Double(1.)); + return Ok(()) + }, OPCode::BiPush | OPCode::SiPush | OPCode::Ldc | OPCode::Ldc2W => match &inst.operands { - Some(params) => Ok(self.push(params[0])), + Some(params) => { + self.push(params[0]); + return Ok(()) + }, None => Err(RuntimeError { kind: RuntimeErrorKind::MissingOperands(inst.mnemonic), }), @@ -465,7 +507,10 @@ impl Runtime { }) }, |params| match params.get(0) { - Some(Value::Int(v)) => Ok(self.load(*v as usize)), + Some(Value::Int(v)) => { + self.load(*v as usize); + return Ok(()) + }, _ => Err(RuntimeError { kind: RuntimeErrorKind::InvalidOperandType( inst.mnemonic, @@ -476,19 +521,31 @@ impl Runtime { OPCode::ILoad0 | OPCode::LLoad0 | OPCode::FLoad0 - | OPCode::DLoad0 => Ok(self.load(0)), + | OPCode::DLoad0 => { + self.load(0); + return Ok(()) + }, OPCode::ILoad1 | OPCode::LLoad1 | OPCode::FLoad1 - | OPCode::DLoad1 => Ok(self.load(1)), + | OPCode::DLoad1 => { + self.load(1); + return Ok(()) + }, OPCode::ILoad2 | OPCode::LLoad2 | OPCode::FLoad2 - | OPCode::DLoad2 => Ok(self.load(2)), + | OPCode::DLoad2 => { + self.load(2); + return Ok(()) + }, OPCode::ILoad3 | OPCode::LLoad3 | OPCode::FLoad3 - | OPCode::DLoad3 => Ok(self.load(3)), + | OPCode::DLoad3 => { + self.load(3); + return Ok(()) + }, // Store operations. OPCode::IStore | OPCode::LStore @@ -502,7 +559,10 @@ impl Runtime { }) }, |params| match params.get(0) { - Some(Value::Int(v)) => Ok(self.store(*v as usize)), + Some(Value::Int(v)) => { + self.store(*v as usize); + return Ok(()) + }, _ => Err(RuntimeError { kind: RuntimeErrorKind::InvalidOperandType( inst.mnemonic, @@ -513,26 +573,39 @@ impl Runtime { OPCode::IStore0 | OPCode::LStore0 | OPCode::FStore0 - | OPCode::DStore0 => Ok(self.store(0)), + | OPCode::DStore0 => { + self.store(0); + return Ok(()) + }, OPCode::IStore1 | OPCode::LStore1 | OPCode::FStore1 - | OPCode::DStore1 => Ok(self.store(1)), + | OPCode::DStore1 => { + self.store(1); + return Ok(()) + }, OPCode::IStore2 | OPCode::LStore2 | OPCode::FStore2 - | OPCode::DStore2 => Ok(self.store(2)), + | OPCode::DStore2 => { + self.store(2); + return Ok(()) + }, OPCode::IStore3 | OPCode::LStore3 | OPCode::FStore3 - | OPCode::DStore3 => Ok(self.store(3)), + | OPCode::DStore3 => { + self.store(3); + return Ok(()) + }, // Arithmetic operations. OPCode::IAdd | OPCode::LAdd | OPCode::FAdd | OPCode::DAdd => { let rhs = self.pop(); let lhs = self.pop(); if let (Some(a), Some(b)) = (lhs, rhs) { - Ok(self.push(Value::add(&a, &b))) + self.push(Value::add(&a, &b)); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -544,7 +617,8 @@ impl Runtime { let lhs = self.pop(); if let (Some(a), Some(b)) = (lhs, rhs) { - Ok(self.push(Value::sub(&a, &b))) + self.push(Value::sub(&a, &b)); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -556,7 +630,8 @@ impl Runtime { let lhs = self.pop(); if let (Some(a), Some(b)) = (lhs, rhs) { - Ok(self.push(Value::mul(&a, &b))) + self.push(Value::mul(&a, &b)); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -568,7 +643,8 @@ impl Runtime { let lhs = self.pop(); if let (Some(a), Some(b)) = (lhs, rhs) { - Ok(self.push(Value::div(&a, &b))) + self.push(Value::div(&a, &b)); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -580,7 +656,8 @@ impl Runtime { let lhs = self.pop(); if let (Some(a), Some(b)) = (lhs, rhs) { - Ok(self.push(Value::rem(&a, &b))) + self.push(Value::rem(&a, &b)); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -630,19 +707,23 @@ impl Runtime { // Type conversion operations. OPCode::L2I | OPCode::F2I | OPCode::D2I => { let val = self.pop(); - Ok(self.push(val.expect("expected value").to_int())) + self.push(val.expect("expected value").to_int()); + return Ok(()) } OPCode::I2F | OPCode::L2F | OPCode::D2F => { let val = self.pop(); - Ok(self.push(val.expect("expected value").to_float())) + self.push(val.expect("expected value").to_float()); + return Ok(()) } OPCode::I2D | OPCode::L2D | OPCode::F2D => { let val = self.pop(); - Ok(self.push(val.expect("expected value").to_double())) + self.push(val.expect("expected value").to_double()); + return Ok(()) } OPCode::I2L | OPCode::F2L | OPCode::D2L => { let val = self.pop(); - Ok(self.push(val.expect("expected value").to_long())) + self.push(val.expect("expected value").to_long()); + return Ok(()) } // Comparison operations. OPCode::LCmp @@ -654,7 +735,8 @@ impl Runtime { let lhs = self.pop(); if let (Some(a), Some(b)) = (lhs, rhs) { - Ok(self.push(Value::Int(Value::compare(&a, &b)))) + self.push(Value::Int(Value::compare(&a, &b))); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -929,7 +1011,8 @@ impl Runtime { |params| Self::get_relative_offset(params), ); - Ok(self.jump(relative_offset)) + self.jump(relative_offset); + return Ok(()) } // Return with value. OPCode::IReturn @@ -940,7 +1023,8 @@ impl Runtime { let value = frame.stack.pop().unwrap(); // This is for debugging purposes. self.return_values.push(value); - Ok(self.push(value)) + self.push(value); + return Ok(()) } else { Err(RuntimeError { kind: RuntimeErrorKind::InvalidValue, @@ -963,7 +1047,8 @@ impl Runtime { }, _ => panic!("InvokeStatic expected parameters"), }; - Ok(self.invoke(*name_index as usize)) + self.invoke(*name_index as usize); + return Ok(()) } // Currently only supports System.out.println. OPCode::InvokeVirtual => {