Implemented a lot of opcodes and some native methods
This commit is contained in:
parent
4c43e9290f
commit
272a34b7cd
5 changed files with 394 additions and 101 deletions
|
@ -87,7 +87,7 @@ impl JavaLangClass {
|
|||
1 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let boolean_class_ref = jvm.class_store.primitive_classes.boolean_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(boolean_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(boolean_class_ref)))
|
||||
} else {
|
||||
let byte_class_ref = jvm.class_store.primitive_classes.byte_class;
|
||||
let byte_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -114,7 +114,7 @@ impl JavaLangClass {
|
|||
2 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let char_class_ref = jvm.class_store.primitive_classes.char_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(char_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(char_class_ref)))
|
||||
} else {
|
||||
let char_class_ref = jvm.class_store.primitive_classes.char_class;
|
||||
let char_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -141,7 +141,7 @@ impl JavaLangClass {
|
|||
3 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let short_class_ref = jvm.class_store.primitive_classes.short_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(short_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(short_class_ref)))
|
||||
} else {
|
||||
let short_class_ref = jvm.class_store.primitive_classes.short_class;
|
||||
let short_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -168,7 +168,7 @@ impl JavaLangClass {
|
|||
4 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let int_class_ref = jvm.class_store.primitive_classes.int_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(int_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(int_class_ref)))
|
||||
} else {
|
||||
let int_class_ref = jvm.class_store.primitive_classes.int_class;
|
||||
let int_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -195,7 +195,7 @@ impl JavaLangClass {
|
|||
5 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let float_class_ref = jvm.class_store.primitive_classes.float_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(float_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(float_class_ref)))
|
||||
} else {
|
||||
let float_class_ref = jvm.class_store.primitive_classes.float_class;
|
||||
let float_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -222,7 +222,7 @@ impl JavaLangClass {
|
|||
6 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let double_class_ref = jvm.class_store.primitive_classes.double_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(double_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(double_class_ref)))
|
||||
} else {
|
||||
let double_class_ref = jvm.class_store.primitive_classes.double_class;
|
||||
let double_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -249,7 +249,7 @@ impl JavaLangClass {
|
|||
7 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let long_class_ref = jvm.class_store.primitive_classes.long_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(long_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(long_class_ref)))
|
||||
} else {
|
||||
let long_class_ref = jvm.class_store.primitive_classes.long_class;
|
||||
let long_class_name_ref = match jvm.heap_area.object_area.get_object_field(
|
||||
|
@ -276,17 +276,55 @@ impl JavaLangClass {
|
|||
8 => {
|
||||
if wrap_stackframe_error(class, method, frame.operand_stack.pop_int(0))? == 1 {
|
||||
let long_class_ref = jvm.class_store.primitive_classes.long_class;
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(long_class_ref)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(long_class_ref)))
|
||||
} else {
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(ObjectReference::NULL)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(ObjectReference::NULL)))
|
||||
}
|
||||
}
|
||||
_ => Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(ObjectReference::NULL)))
|
||||
_ => Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(ObjectReference::NULL)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn desired_assertion_status_0(_: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(1)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(1)))
|
||||
}
|
||||
}
|
||||
|
||||
struct JavaLangFloat {}
|
||||
|
||||
impl JavaLangFloat {
|
||||
pub fn float_to_raw_int_bits(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||
let frame = {
|
||||
let frame_index = jvm.stack_frames.len() - 1;
|
||||
&mut jvm.stack_frames[frame_index]
|
||||
};
|
||||
let class = jvm.class_store.class_file_from_idx(frame.class_index).unwrap();
|
||||
let method = & class.methods[frame.method_index as usize];
|
||||
|
||||
let float_value = wrap_stackframe_error(class, method, frame.load_local_float(0))?;
|
||||
let ubits = float_value.to_bits();
|
||||
let ibits = i32::from_ne_bytes(ubits.to_ne_bytes());
|
||||
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(ibits)))
|
||||
}
|
||||
}
|
||||
|
||||
struct JavaLangDouble {}
|
||||
|
||||
impl JavaLangDouble {
|
||||
pub fn double_to_raw_long_bits(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||
let frame = {
|
||||
let frame_index = jvm.stack_frames.len() - 1;
|
||||
&mut jvm.stack_frames[frame_index]
|
||||
};
|
||||
let class = jvm.class_store.class_file_from_idx(frame.class_index).unwrap();
|
||||
let method = & class.methods[frame.method_index as usize];
|
||||
|
||||
let double_value = wrap_stackframe_error(class, method, frame.load_local_double(0))?;
|
||||
let ubits = double_value.to_bits();
|
||||
let ibits = i64::from_ne_bytes(ubits.to_ne_bytes());
|
||||
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Long(ibits)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,7 +332,7 @@ struct JavaLangStringUTF16 {}
|
|||
|
||||
impl JavaLangStringUTF16 {
|
||||
pub fn is_big_endian(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(if cfg!(target_endian = "big") {1} else {0})))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(if cfg!(target_endian = "big") {1} else {0})))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,12 +374,12 @@ impl JdkInternalMiscUnsafe {
|
|||
std::mem::size_of::<usize>() as i32
|
||||
};
|
||||
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(index_scale)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(index_scale)))
|
||||
}
|
||||
|
||||
pub fn array_base_offset_0(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
|
||||
// TODO: Check passed class
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Int(0)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(0)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,7 +428,7 @@ impl JdkInternalUtilSystemPropsRaw {
|
|||
|
||||
}
|
||||
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(array_reference)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(array_reference)))
|
||||
}
|
||||
|
||||
// command-line configured properties, should return at least java.home
|
||||
|
@ -404,6 +442,7 @@ impl JdkInternalUtilSystemPropsRaw {
|
|||
("user.country", "US"),
|
||||
("user.variant", ""),
|
||||
("sun.nio.MaxDirectMemorySize", "9223372036854775807"),
|
||||
("sun.nio.PageAlignDirectMemory", "false"),
|
||||
];
|
||||
// TODO: Cross-Platform tmpdir
|
||||
// TODO: locale detection
|
||||
|
@ -420,7 +459,7 @@ impl JdkInternalUtilSystemPropsRaw {
|
|||
jvm.heap_area.object_area.set_array_element(array_reference, index * 2 + 1, value_reference.into());
|
||||
}
|
||||
|
||||
Ok(JVMCallbackOperation::ReturnFrame(StackValue::Reference(array_reference)))
|
||||
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Reference(array_reference)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -921,6 +960,36 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
|
|||
Ok(todo_call)
|
||||
}
|
||||
|
||||
("java/lang/Double", "doubleToRawLongBits") => {
|
||||
let expected_descriptor = MethodDescriptor {
|
||||
argument_types: Box::new([
|
||||
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Double() }
|
||||
]),
|
||||
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Long() },
|
||||
};
|
||||
|
||||
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(JavaLangDouble::double_to_raw_long_bits)
|
||||
}
|
||||
|
||||
("java/lang/Double", "longBitsToDouble") => {
|
||||
let expected_descriptor = MethodDescriptor {
|
||||
argument_types: Box::new([
|
||||
AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Long() }
|
||||
]),
|
||||
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Double() },
|
||||
};
|
||||
|
||||
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(JavaLangDouble::double_to_raw_long_bits)
|
||||
}
|
||||
|
||||
("java/lang/Float", "intBitsToFloat") => {
|
||||
let expected_descriptor = MethodDescriptor {
|
||||
argument_types: Box::new([
|
||||
|
@ -948,7 +1017,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(JavaLangFloat::float_to_raw_int_bits)
|
||||
}
|
||||
|
||||
("java/lang/String", "intern") => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue