From 49ce37402ea68c5774d94f7051f0e68ff9ae6cc9 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Wed, 11 Sep 2024 00:25:37 +0200 Subject: [PATCH] Find implementation of invokeinterface method --- src/jvm.rs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/jvm.rs b/src/jvm.rs index bb3f02f..06a3e3e 100644 --- a/src/jvm.rs +++ b/src/jvm.rs @@ -1019,19 +1019,9 @@ impl JVM { let target_interface_class_index = self.class_store.class_idx_from_name(supplied_interface_name).unwrap(); let parsed_expected_descriptor: MethodDescriptor = MethodDescriptor::try_from(supplied_descriptor_string)?; - let (class_index, method_index, method_info) = match ClassMethodIterator::new(target_interface_class_index, &self.class_store) - .filter(|(_cid, _mid, minfo)| minfo.name == *supplied_method_name) - .filter(|(_cid, _mid, minfo)| minfo.descriptor == parsed_expected_descriptor) - .next() { - Some(m) => m, - None => { - // TODO: Throw exception - return Err(Error::RunTimeError(format!("InvokeInterface: Failed to find requested method '{}' with descriptor '{}' in the class '{}'", supplied_method_name, supplied_descriptor_string, supplied_interface_name))); - } - }; let mut arguments = VecDeque::new(); - fill_arguments(class, method, &mut arguments, &method_info.descriptor.argument_types, &mut frame.operand_stack)?; + fill_arguments(class, method, &mut arguments, &parsed_expected_descriptor.argument_types, &mut frame.operand_stack)?; let this_object = wrap_stackframe_error(class, method, frame.operand_stack.pop_reference(0))?; arguments.push_front(StackValue::Reference(this_object)); @@ -1048,11 +1038,24 @@ impl JVM { } } - // TODO: I hate this, now I have to find the 'implementation' of a function - let interface_class_file = self.class_store.class_file_from_idx(target_interface_class_index).unwrap(); + // TODO: Filter abstract + // TODO: Check method info match + let (class_index, method_index, _method_info) = match ClassMethodIterator::new(object_class_index, &self.class_store) + .filter(|(_cid, _mid, minfo)| minfo.name == *supplied_method_name) + .filter(|(_cid, _mid, minfo)| minfo.descriptor == parsed_expected_descriptor) + .next() { + Some(m) => m, + None => { + // TODO: Throw exception + return Err(Error::RunTimeError(format!("InvokeInterface: Failed to find requested implementation of method '{}' with descriptor '{}' in the class '{}'", supplied_method_name, supplied_descriptor_string, supplied_interface_name))); + } + }; + + + let implementing_class_file = self.class_store.class_file_from_idx(class_index).unwrap(); let interface_frame = StackFrame::new( - interface_class_file, - target_interface_class_index, + implementing_class_file, + class_index, method_index as u16, arguments.make_contiguous() );