Implemented catchall in ::EntryPoint
This commit is contained in:
parent
6b03cab14d
commit
f5428c79b2
3 changed files with 109 additions and 8 deletions
70
src/jvm.rs
70
src/jvm.rs
|
@ -1,3 +1,4 @@
|
|||
use crate::classfile::ExceptionTableEntry;
|
||||
use core::fmt::{Display, Formatter};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
|
@ -9,7 +10,7 @@ use crate::classfile;
|
|||
use crate::classfile::{ JavaClassFile, FieldInfo, MethodInfo, MethodDescriptor, AbstractTypeDescription, AbstractTypeKind, AttributeInfo, AttributeData, CodeAttributeData, ConstantValueAttributeData };
|
||||
use crate::classstore;
|
||||
use crate::classstore::ClassStore;
|
||||
use crate::constantpool::{ ConstantPoolInfo, ConstantClassInfo, ConstantUtf8Info, ConstantMethodRefInfo, ConstantNameAndTypeInfo};
|
||||
use crate::constantpool::{ ConstantClassInfo, ConstantInterfaceMethodRefInfo, ConstantMethodRefInfo, ConstantNameAndTypeInfo, ConstantPoolInfo, ConstantUtf8Info};
|
||||
use crate::heap_area::{ HeapArea, FieldValue, ObjectReference, CompartmentEntry };
|
||||
use crate::iterators::{ ClassMethodIterator, ClassFieldIterator };
|
||||
use crate::native_methods;
|
||||
|
@ -259,7 +260,12 @@ impl JVM {
|
|||
ConstantPoolInfo::Class(ConstantClassInfo { name_index: 18 }),
|
||||
ConstantPoolInfo::Utf8(ConstantUtf8Info { utf8: "java/lang/System".to_string() }),
|
||||
ConstantPoolInfo::NameAndType(ConstantNameAndTypeInfo { name_index: 20, descriptor_index: 13 }),
|
||||
ConstantPoolInfo::Utf8(ConstantUtf8Info { utf8: "initPhase1".to_string() }),
|
||||
ConstantPoolInfo::Utf8(ConstantUtf8Info { utf8: "initPhase1".to_string() }), // 20
|
||||
ConstantPoolInfo::InterfaceMethodRef(ConstantInterfaceMethodRefInfo { class_index: 22, name_and_type_index: 24}),
|
||||
ConstantPoolInfo::Class(ConstantClassInfo { name_index: 23 }),
|
||||
ConstantPoolInfo::Utf8(ConstantUtf8Info { utf8: "java/lang/Throwable".to_string() }),
|
||||
ConstantPoolInfo::NameAndType(ConstantNameAndTypeInfo { name_index: 25, descriptor_index: 13 }),
|
||||
ConstantPoolInfo::Utf8(ConstantUtf8Info { utf8: "printStackTrace".to_string() }), // 25
|
||||
]
|
||||
),
|
||||
access_flags: ClassAccessFlagMask { mask: ClassAccessFlag::Super.discriminant() },
|
||||
|
@ -309,9 +315,24 @@ impl JVM {
|
|||
0xB8_u8.to_be(), // invokestatic
|
||||
0x04_u16.to_be_bytes()[0], // index 4 into the constant
|
||||
0x04_u16.to_be_bytes()[1], // pool
|
||||
|
||||
0xB1_u8.to_be(), // returnvoid
|
||||
// index 14
|
||||
|
||||
0xB9_u8.to_be(), // invokeinterface
|
||||
21_u16.to_be_bytes()[0], // index 21 constant
|
||||
21_u16.to_be_bytes()[1], // index 21 constant
|
||||
0x00_u8.to_be(), // constant 0
|
||||
]),
|
||||
},
|
||||
exception_table: Box::new([]),
|
||||
exception_table: Box::new([
|
||||
ExceptionTableEntry {
|
||||
start_pc: 0,
|
||||
end_pc: u16::MAX,
|
||||
handler_pc: 14,
|
||||
catch_type: 0, // Catchall
|
||||
}
|
||||
]),
|
||||
attributes: Box::new([]),
|
||||
}
|
||||
)
|
||||
|
@ -460,6 +481,43 @@ impl JVM {
|
|||
JVMCallbackOperation::MakeArrayClass(component_class_ref, component_descriptor) => {
|
||||
self.make_array_class(component_class_ref, component_descriptor);
|
||||
}
|
||||
|
||||
JVMCallbackOperation::ThrowException(exception) => {
|
||||
let mut is_handler_found = false;
|
||||
while ! is_handler_found {
|
||||
is_handler_found = {
|
||||
let frame = {
|
||||
let frame_index = self.stack_frames.len() - 1;
|
||||
&mut self.stack_frames[frame_index]
|
||||
};
|
||||
let class = self.class_store.class_file_from_idx(frame.class_index).unwrap();
|
||||
let method = &class.methods[frame.method_index as usize];
|
||||
if method.is_native() {
|
||||
false
|
||||
} else {
|
||||
class.is_method_bytecode_protected(method, frame.instruction_pointer as u16, exception)
|
||||
}
|
||||
};
|
||||
|
||||
if ! is_handler_found {
|
||||
self.stack_frames.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if is_handler_found {
|
||||
let frame = {
|
||||
let frame_index = self.stack_frames.len() - 1;
|
||||
&mut self.stack_frames[frame_index]
|
||||
};
|
||||
let class = self.class_store.class_file_from_idx(frame.class_index).unwrap();
|
||||
let method = &class.methods[frame.method_index as usize];
|
||||
frame.operand_stack.clear();
|
||||
wrap_stackframe_error(class, method, frame.operand_stack.push(StackValue::Reference(exception)))?;
|
||||
frame.instruction_pointer = method.get_protected_handler_pc(frame.instruction_pointer as u16).unwrap() as u32;
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2281,7 +2339,10 @@ impl JVM {
|
|||
Instruction::ThrowException() => {
|
||||
let exception = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?;
|
||||
if exception == ObjectReference::NULL {
|
||||
|
||||
// TODO: Throw NullPointerException
|
||||
} else {
|
||||
// TODO: Check throwable instance
|
||||
return Ok(JVMCallbackOperation::ThrowException(exception));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2312,6 +2373,7 @@ pub enum JVMCallbackOperation {
|
|||
LoadClass(String),
|
||||
InitClass(String),
|
||||
MakeArrayClass(ObjectReference, AbstractTypeDescription),
|
||||
ThrowException(ObjectReference),
|
||||
}
|
||||
|
||||
fn load_local_reference(class: &JavaClassFile, method: &MethodInfo, frame: &mut StackFrame, index: usize) -> Result<(), Error> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue