diff --git a/src/class.rs b/src/class.rs index 6f49af2..f7db82a 100644 --- a/src/class.rs +++ b/src/class.rs @@ -23,17 +23,9 @@ pub fn get_class(vm: &mut Vm, _calling_class_name: Option<&str>, class_name: &st println!("get_class {}", class_name); unsafe { - // not pretty...sorry - // if let Some(calling_class_name) = calling_class_name { - // if class_name == calling_class_name { // works around the situation that static initializer needs a ref to the class it's in - // return Ok(CLASSDEFS.get(class_name.into()).unwrap().clone()); // in that case the class is guaranteed to be here - // } - // } - let class = CLASSDEFS.entry(class_name.into()).or_insert_with(|| { println!("read class {} ", class_name); let resolved_path = find_class(&vm.classpath, class_name).unwrap(); - // println!("full path {}", resolved_path); let bytecode = read_bytecode(resolved_path).unwrap(); let class = load_class(bytecode).unwrap(); Arc::new(RefCell::new(class)) diff --git a/src/opcodes.rs b/src/opcodes.rs index 2d209de..030bcb9 100644 --- a/src/opcodes.rs +++ b/src/opcodes.rs @@ -118,6 +118,13 @@ pub const fcmpl: u8 = 149; // (0x95) Compare float (less than) pub const fcmpg: u8 = 150; // (0x96) Compare float (greater than) pub const dcmpl: u8 = 151; // (0x97) compare double (less than) pub const dcmpg: u8 = 152; // (0x98) compare double (greater than) +pub const IF_ICMPEQ:u8 = 159; // (0x9f) Branch if int comparison succeeds +pub const IF_ICMPNE:u8 = 160; // (0x9f) Branch if int comparison succeeds +pub const IF_ICMPLT:u8 = 161; // (0x9f) Branch if int comparison succeeds +pub const IF_ICMPGE:u8 = 162; // (0x9f) Branch if int comparison succeeds +pub const IF_ICMPGT:u8 = 163; // (0x9f) Branch if int comparison succeeds +pub const IF_ICMPLE:u8 = 164; // (0x9f) Branch if int comparison succeeds +pub const GOTO: u8 = 167; // (0xa7) Branch always pub const IRETURN: u8 = 172; // (0xac) ireturn pub const FRETURN: u8 = 174; // (0xae) Return float from method diff --git a/src/vm.rs b/src/vm.rs index 7290be5..7da9156 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -121,8 +121,8 @@ impl Vm { let mut pc = &mut 0; while *pc < code.opcodes.len() { let opcode = read_u8(&code.opcodes, pc); - let f= self.current_frame(); - print!("at {}: stack {}, opcode {}: ", f.at, f.len(), opcode); + let f = self.current_frame(); + print!("at {}: stack {}, #{}: opcode {}: ", f.at, f.len(), *pc-1, opcode); match opcode { ACONST_NULL => { println!("ACONST"); @@ -312,7 +312,8 @@ impl Vm { } BASTORE | IASTORE | LASTORE | CASTORE | SASTORE | FASTORE | DASTORE | AASTORE => unsafe { println!("ASTORE"); - self.array_store()? }, + self.array_store()? + }, POP => { println!("POP"); self.current_frame().pop()?; @@ -323,6 +324,38 @@ impl Vm { self.current_frame().push_ref(value.clone()); self.current_frame().push_ref(value); } + IF_ICMPEQ | IF_ICMPNE | IF_ICMPGT | IF_ICMPGE | IF_ICMPLT | IF_ICMPLE => { + + let jmp_to = read_u16(&code.opcodes, pc); + let value1 = self.current_frame().pop()?; + let value2 = self.current_frame().pop()?; + unsafe { + if let I32(value1) = *value1.get() { + if let I32(value2) = *value2.get() { + let jump = match opcode { + IF_ICMPEQ => { value1 == value2 } + IF_ICMPNE => { value1 != value2 } + IF_ICMPGT => { value1 > value2 } + IF_ICMPGE => { value1 >= value2 } + IF_ICMPLT => { value1 < value2 } + IF_ICMPLE => { value1 <= value2 } + _ => { false } + }; + if jump { + println!("JMP {}", jmp_to); + *pc = jmp_to as usize; + } else { + println!("NO JMP {}", jmp_to); + } + } + } + } + } + GOTO => { + let jmp_to = read_u16(&code.opcodes, pc); + println!("GOTO {}", jmp_to); + *pc = jmp_to as usize; + } IRETURN | FRETURN | DRETURN => { println!("RETURN"); let result = self.current_frame().pop();