Implemented java/lang/Throwable.fill_in_stacktrace

This commit is contained in:
vegowotenks 2024-11-07 14:07:14 +01:00
parent d38d5b2897
commit 45d0aa66e5
2 changed files with 128 additions and 2 deletions

View file

@ -350,7 +350,7 @@ struct JavaLangSystem {}
impl JavaLangSystem {
pub fn arraycopy(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
let frame = {
let frame = {
let frame_index = jvm.stack_frames.len() - 1;
&mut jvm.stack_frames[frame_index]
};
@ -372,7 +372,93 @@ impl JavaLangSystem {
struct JavaLangThrowable {}
impl JavaLangThrowable {
pub fn fill_in_stacktrace(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
if ! jvm.class_store.have_class(&String::from("java/lang/StackTraceElement")) {
return Ok(JVMCallbackOperation::LoadClass(String::from("java/lang/StackTraceElement")));
}
if ! jvm.class_store.was_init(&String::from("java/lang/StackTraceElement")).unwrap() {
return Ok(JVMCallbackOperation::LoadClass(String::from("java/lang/StackTraceElement")));
}
let stackelement_class_index = jvm.class_store.class_idx_from_name(&String::from("java/lang/StackTraceElement")).unwrap();
let stackelement_class_ref = jvm.class_store.get_class_objectref_from_index(stackelement_class_index);
let stackelement_type = AbstractTypeDescription::class_type("java/lang/StackTraceElement");
let _ = match jvm.class_store.get_array_class_ref(&stackelement_type.array()) {
Some(r) => r,
None => return Ok(JVMCallbackOperation::MakeArrayClass(stackelement_class_ref, stackelement_type)),
};
let this = {
let frame = {
let frame_index = jvm.stack_frames.len() - 1;
&jvm.stack_frames[frame_index]
};
frame.load_local_reference(0).unwrap()
};
let stackelement_array = jvm.heap_area.make_empty_array(&jvm.class_store, AbstractTypeDescription::class_type("java/lang/StackTraceElement"), jvm.stack_frames.len());
jvm.heap_area.object_area.set_object_field(
this,
"stackTrace",
stackelement_array.into(),
stackelement_class_index,
&jvm.class_store
)?;
for (index, frame) in (&jvm.stack_frames).into_iter().enumerate() {
let class_file = jvm.class_store.class_file_from_idx(frame.class_index).unwrap();
let method_info = &class_file.methods[frame.method_index as usize];
let class_name = class_file.get_classname()?;
let line_number = method_info.get_bytecode_linenumber(frame.instruction_pointer.try_into().unwrap());
let stackelement = jvm.heap_area.make_object(&jvm.class_store, stackelement_class_index);
let class_name_string = jvm.heap_area.make_handmade_string(class_name, &jvm.class_store);
let method_name_string = jvm.heap_area.make_handmade_string(&method_info.name, &jvm.class_store);
let sourcefile = class_file.sourcefile()?;
let sourcefile_string = match sourcefile {
Some(string) => jvm.heap_area.make_handmade_string(string, &jvm.class_store),
None => jvm.heap_area.static_area.get(&String::from("StackTraceElement"), &String::from("UNKNOWN_SOURCE"), AbstractTypeDescription::class_type("java/lang/String")).unwrap().expect_reference(),
};
jvm.heap_area.object_area.set_object_field(
stackelement,
"declaringClass",
FieldValue::Reference(class_name_string),
stackelement_class_index,
&jvm.class_store
)?;
jvm.heap_area.object_area.set_object_field(
stackelement,
"methodName",
FieldValue::Reference(method_name_string),
stackelement_class_index,
&jvm.class_store
)?;
jvm.heap_area.object_area.set_object_field(
stackelement,
"lineNumber",
FieldValue::Int(line_number.unwrap_or(1) as i32),
stackelement_class_index,
&jvm.class_store
)?;
jvm.heap_area.object_area.set_object_field(
stackelement,
"fileName",
FieldValue::Reference(sourcefile_string),
stackelement_class_index,
&jvm.class_store
)?;
jvm.heap_area.object_area.set_array_element(stackelement_array, index, stackelement.into());
}
Ok(JVMCallbackOperation::ReturnFrame(this.into()))
}
}
struct JdkInternalMiscUnsafe {}
@ -2861,7 +2947,7 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
]),
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Throwable".to_string())},
},
JavaLangThrowable::fill_in_stacktrace()
JavaLangThrowable::fill_in_stacktrace
),
];