added some conditional jumps and goto

This commit is contained in:
Shautvast 2023-10-19 21:09:53 +02:00
parent 29d672db50
commit 736a13a2d0
3 changed files with 43 additions and 11 deletions

View file

@ -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))

View file

@ -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

View file

@ -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();