added some conditional jumps and goto
This commit is contained in:
parent
29d672db50
commit
736a13a2d0
3 changed files with 43 additions and 11 deletions
|
|
@ -23,17 +23,9 @@ pub fn get_class(vm: &mut Vm, _calling_class_name: Option<&str>, class_name: &st
|
||||||
println!("get_class {}", class_name);
|
println!("get_class {}", class_name);
|
||||||
|
|
||||||
unsafe {
|
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(|| {
|
let class = CLASSDEFS.entry(class_name.into()).or_insert_with(|| {
|
||||||
println!("read class {} ", class_name);
|
println!("read class {} ", class_name);
|
||||||
let resolved_path = find_class(&vm.classpath, class_name).unwrap();
|
let resolved_path = find_class(&vm.classpath, class_name).unwrap();
|
||||||
// println!("full path {}", resolved_path);
|
|
||||||
let bytecode = read_bytecode(resolved_path).unwrap();
|
let bytecode = read_bytecode(resolved_path).unwrap();
|
||||||
let class = load_class(bytecode).unwrap();
|
let class = load_class(bytecode).unwrap();
|
||||||
Arc::new(RefCell::new(class))
|
Arc::new(RefCell::new(class))
|
||||||
|
|
|
||||||
|
|
@ -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 fcmpg: u8 = 150; // (0x96) Compare float (greater than)
|
||||||
pub const dcmpl: u8 = 151; // (0x97) compare double (less than)
|
pub const dcmpl: u8 = 151; // (0x97) compare double (less than)
|
||||||
pub const dcmpg: u8 = 152; // (0x98) compare double (greater 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 IRETURN: u8 = 172; // (0xac) ireturn
|
||||||
pub const FRETURN: u8 = 174; // (0xae) Return float from method
|
pub const FRETURN: u8 = 174; // (0xae) Return float from method
|
||||||
|
|
|
||||||
39
src/vm.rs
39
src/vm.rs
|
|
@ -121,8 +121,8 @@ impl Vm {
|
||||||
let mut pc = &mut 0;
|
let mut pc = &mut 0;
|
||||||
while *pc < code.opcodes.len() {
|
while *pc < code.opcodes.len() {
|
||||||
let opcode = read_u8(&code.opcodes, pc);
|
let opcode = read_u8(&code.opcodes, pc);
|
||||||
let f= self.current_frame();
|
let f = self.current_frame();
|
||||||
print!("at {}: stack {}, opcode {}: ", f.at, f.len(), opcode);
|
print!("at {}: stack {}, #{}: opcode {}: ", f.at, f.len(), *pc-1, opcode);
|
||||||
match opcode {
|
match opcode {
|
||||||
ACONST_NULL => {
|
ACONST_NULL => {
|
||||||
println!("ACONST");
|
println!("ACONST");
|
||||||
|
|
@ -312,7 +312,8 @@ impl Vm {
|
||||||
}
|
}
|
||||||
BASTORE | IASTORE | LASTORE | CASTORE | SASTORE | FASTORE | DASTORE | AASTORE => unsafe {
|
BASTORE | IASTORE | LASTORE | CASTORE | SASTORE | FASTORE | DASTORE | AASTORE => unsafe {
|
||||||
println!("ASTORE");
|
println!("ASTORE");
|
||||||
self.array_store()? },
|
self.array_store()?
|
||||||
|
},
|
||||||
POP => {
|
POP => {
|
||||||
println!("POP");
|
println!("POP");
|
||||||
self.current_frame().pop()?;
|
self.current_frame().pop()?;
|
||||||
|
|
@ -323,6 +324,38 @@ impl Vm {
|
||||||
self.current_frame().push_ref(value.clone());
|
self.current_frame().push_ref(value.clone());
|
||||||
self.current_frame().push_ref(value);
|
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 => {
|
IRETURN | FRETURN | DRETURN => {
|
||||||
println!("RETURN");
|
println!("RETURN");
|
||||||
let result = self.current_frame().pop();
|
let result = self.current_frame().pop();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue