Implemented some more native methods

This commit is contained in:
vegowotenks 2024-11-03 23:03:10 +01:00
parent 272a34b7cd
commit aba29af0a3
5 changed files with 198 additions and 6 deletions

View file

@ -1,9 +1,9 @@
use crate::stackframe::StackFrame;
use crate::heap_area::ObjectReference;
use crate::heap_area::FieldValue;
use crate::jvm::wrap_stackframe_error;
use crate::stackframe::StackValue;
use crate::iterators::ClassFieldIterator;
use crate::classfile::{ AbstractTypeDescription, AbstractTypeKind, MethodDescriptor };
use crate::native_registry::NativeMethodCallable;
use crate::jvm::JVM;
@ -328,6 +328,14 @@ impl JavaLangDouble {
}
}
struct JavaLangRuntime {}
impl JavaLangRuntime {
pub fn available_processors(_jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Int(1)))
}
}
struct JavaLangStringUTF16 {}
impl JavaLangStringUTF16 {
@ -339,6 +347,29 @@ impl JavaLangStringUTF16 {
struct JdkInternalMiscUnsafe {}
impl JdkInternalMiscUnsafe {
pub fn object_field_offset_1(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
// args: Class class, String fieldName
let frame = {
let frame_index = jvm.stack_frames.len() - 1;
&mut jvm.stack_frames[frame_index]
};
let class_object_reference = frame.load_local_reference(1).unwrap();
let class_descriptor = jvm.heap_area.object_area.get_class_ref_native_class_name(class_object_reference, &jvm.class_store);
let class_index = jvm.class_store.class_index_for_type(AbstractTypeDescription::parse_full(class_descriptor).unwrap()).unwrap();
let field_name_string_reference = frame.load_local_reference(2).unwrap();
let rust_field_name_string = jvm.heap_area.decode_java_string(field_name_string_reference, &jvm.class_store);
let byte_offset: i64 = ClassFieldIterator::new(class_index as usize, &jvm.class_store)
.take_while(|f| f.name != rust_field_name_string)
.map(|f| f.descriptor.storage_size() as i64)
.sum();
Ok(JVMCallbackOperation::ReturnFrame(FieldValue::Long(byte_offset)))
}
pub fn array_index_scale_0(jvm: &mut JVM) -> Result<JVMCallbackOperation, Error> {
let frame = {
let frame_index = jvm.stack_frames.len() - 1;
@ -1127,6 +1158,71 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
Ok(todo_call)
}
("java/lang/Runtime", "availableProcessors") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),
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(JavaLangRuntime::available_processors)
}
("java/lang/Runtime", "freeMemory") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),
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(todo_call)
}
("java/lang/Runtime", "gc") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Void()},
};
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/Runtime", "maxMemory") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),
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(todo_call)
}
("java/lang/Runtime", "totalMemory") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),
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(todo_call)
}
("java/lang/System", "arraycopy") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([
@ -1263,6 +1359,19 @@ pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Resul
Ok(todo_call)
}
("java/lang/Thread", "registerNatives") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([]),
return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Void()},
};
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(ignore_call)
}
("jdk/internal/misc/Unsafe", "arrayBaseOffset0") => {
let expected_descriptor = MethodDescriptor {
argument_types: Box::new([
@ -2149,7 +2258,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(JdkInternalMiscUnsafe::object_field_offset_1)
}
("jdk/internal/misc/Unsafe", "registerNatives") => {