use crate::classfile::{ AbstractTypeDescription, AbstractTypeKind, MethodDescriptor }; use crate::native_registry::NativeMethodCallable; use crate::jvm::JVM; use crate::jvm::Error; use crate::jvm::JVMCallbackOperation; pub fn ignore_call(_: &mut JVM) -> Result { Ok(JVMCallbackOperation::PopFrame()) } pub fn todo_call(_: &mut JVM) -> Result { todo!() } pub fn java_lang_object_get_class(jvm: &mut JVM) -> Result { todo!() } pub fn function_for(class_name: &str, m: &crate::classfile::MethodInfo) -> Result { let method_name: &str = &m.name; match (class_name, method_name) { ("java/lang/Class", "forName0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string()) }, AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() }, AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/ClassLoader".to_string()) }, AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, ]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname(String::from("java/lang/Class"))}, }; 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/Class", "desiredAssertionStatus0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, ]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "getClassAccessFlagsRaw0") => { 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(todo_call) } ("java/lang/Class", "getClassFileVersion0") => { 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(todo_call) } ("java/lang/Class", "getConstantPool") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ ]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("jdk/internal/reflect/ConstantPool".to_string()) }, }; 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/Class", "getDeclaredClasses0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getDeclaredConstructors0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() }, ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/reflect/Constructor".to_string()) }, }; 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/Class", "getDeclaredFields0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() }, ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/reflect/Field".to_string()) }, }; 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/Class", "getDeclaredMethods0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean() }, ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/reflect/Method".to_string()) }, }; 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/Class", "getDeclaringClass0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getEnclosingMethod0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Object".to_string()) }, }; 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/Class", "getGenericSignature0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string()) }, }; 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/Class", "getInterfaces0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getNestMembers0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getModifiers") => { 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(todo_call) } ("java/lang/Class", "getNestHost0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getPermittedSubclasses0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getPrimitiveClass") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string()) }, ]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "getProtectionDomain0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/security/ProtectionDomain".to_string()) }, }; 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/Class", "getRawAnnotations") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Byte() }, }; 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/Class", "getRawTypeAnnotations") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Byte() }, }; 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/Class", "getRecordComponents0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ ]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/reflect/RecordComponent".to_string()) }, }; 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/Class", "getSimpleBinaryName0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string()) }, }; 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/Class", "getSigners") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Object".to_string()) }, }; 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/Class", "getSuperclass") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, }; 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/Class", "isAssignableFrom") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Class".to_string()) }, ]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "initClassName") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/String".to_string()) }, }; 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/Class", "isArray") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "isHidden") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "isInstance") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname("java/lang/Object".to_string()) }, ]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "isInterface") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "isPrimitive") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "isRecord0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Boolean()}, }; 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/Class", "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(todo_call) } ("java/lang/Class", "setSigners") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 1, kind: AbstractTypeKind::Classname("java/lang/Object".to_string()) } ]), 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/String", "intern") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname(String::from("java/lang/String"))}, }; 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/Object", "clone") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname(String::from("java/lang/Object"))}, }; 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/Object", "getClass") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([]), return_type: AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Classname(String::from("java/lang/Class"))}, }; 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(java_lang_object_get_class) } ("java/lang/Object", "hashCode") => { 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(todo_call) } ("java/lang/Object", "notifyAll") => { 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/Object", "notify") => { 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/Object", "wait0") => { let expected_descriptor = MethodDescriptor { argument_types: Box::new([ AbstractTypeDescription { array_level: 0, kind: AbstractTypeKind::Long() }, ]), 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) } _ => Err(Error::RunTimeError(format!("Failed to find native implementation for method '{class_name}.{method_name}'"))), } }