Int Branching instructions

This commit is contained in:
vegowotenks 2024-09-10 01:33:35 +02:00
parent ede316cec3
commit 6610b09c16
4 changed files with 283 additions and 82 deletions

View file

@ -1,4 +1,6 @@
use crate::stackframe::StackFrame;
use crate::heap_area::ObjectReference;
use crate::heap_area::FieldValue;
use crate::jvm::wrap_stackframe_error;
use crate::stackframe::StackValue;
@ -40,6 +42,49 @@ impl EntryPoint {
struct JavaLangClass {}
impl JavaLangClass {
pub fn get_primitive_class(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
let frame = {
let frame_index = jvm.stack_frames.len() - 1;
&mut jvm.stack_frames[frame_index]
};
// max_locals: 1
// max_stack: 1
let class_class_index = jvm.class_store.class_idx_from_name(&String::from("java/lang/Class")).unwrap();
let (string_class_file, string_class_index) = jvm.class_store.get_class(&String::from("java/lang/String")).unwrap();
let string_equals_index = string_class_file.find_method_index(&String::from("equals")).unwrap();
let passed_wanted_string = match frame.locals[0] {
StackValue::Reference(r) => r,
_ => unreachable!(),
};
match frame.instruction_pointer {
0 => {
let boolean_class_ref = jvm.class_store.primitive_classes.boolean_class;
let boolean_class_name_ref = match jvm.heap_area.object_area.get_object_field(
boolean_class_ref,
"name",
class_class_index,
&jvm.class_store
).unwrap() {
FieldValue::Reference(r) => r,
_ => unreachable!(),
};
let string_compare_frame = StackFrame::new(
string_class_file,
string_class_index,
string_equals_index as u16,
&[StackValue::Reference(boolean_class_name_ref), StackValue::Reference(passed_wanted_string)],
);
frame.instruction_pointer += 1;
Ok(JVMCallbackOperation::PushFrame(string_compare_frame))
},
_ => Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(ObjectReference::NULL)))
}
}
pub fn desired_assertion_status_0(_: &mut JVM) -> Result<JVMCallbackOperation, Error> {
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(1)))
}
@ -375,7 +420,7 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
return Err(Error::RunTimeError(format!("Native descriptor mismatch for method '{class_name}.{method_name}': found '{}' but expected '{}'", m.descriptor.source_string(), expected_descriptor.source_string())));
}
Ok(todo_call)
Ok(JavaLangClass::get_primitive_class)
}
("java/lang/Class", "getProtectionDomain0") => {
@ -608,6 +653,36 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
Ok(todo_call)
}
("java/lang/Float", "intBitsToFloat") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() }
]),
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Float() },
};
if m.descriptor != expected_descriptor {
return Err(Error::RunTimeError(format!("Native descriptor mismatch for method '{class_name}.{method_name}': found '{}' but expected '{}'", m.descriptor.source_string(), expected_descriptor.source_string())));
}
Ok(todo_call)
}
("java/lang/Float", "floatToRawIntBits") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Float() }
]),
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Int() },
};
if m.descriptor != expected_descriptor {
return Err(Error::RunTimeError(format!("Native descriptor mismatch for method '{class_name}.{method_name}': found '{}' but expected '{}'", m.descriptor.source_string(), expected_descriptor.source_string())));
}
Ok(todo_call)
}
("java/lang/String", "intern") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),