Skip to content

Commit d04e3dc

Browse files
committed
Fix superclass method lookup for invokespecial
1 parent f39c6a0 commit d04e3dc

12 files changed

Lines changed: 74 additions & 3 deletions

‎jvm/src/jvm.rs‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,14 @@ impl Jvm {
435435
tracing::trace!("Invoke special {class_name}.{name}:{descriptor}({args:?})");
436436

437437
let class = self.resolve_class(class_name).await?;
438-
let method = class.definition.method(name, descriptor, false);
438+
let method = if name == "<init>" {
439+
// Constructors are not inherited (JVMS 6.5 invokespecial).
440+
class.definition.method(name, descriptor, false).map(|method| (class, method))
441+
} else {
442+
self.resolve_method(&class, name, descriptor, false)
443+
};
439444

440-
if let Some(method) = method {
445+
if let Some((class, method)) = method {
441446
let args = iter::once(JavaValue::Object(Some(clone_box(&**instance))))
442447
.chain(args.into_vec())
443448
.collect::<Vec<_>>();
@@ -448,6 +453,12 @@ impl Jvm {
448453
.await);
449454
}
450455

456+
if method.access_flags().contains(MethodAccessFlags::ABSTRACT) {
457+
return Err(self
458+
.exception("java/lang/AbstractMethodError", &format!("{class_name}.{name}:{descriptor}"))
459+
.await);
460+
}
461+
451462
Ok(self
452463
.execute_method(&class, Some(instance.clone()), &method, args.into_boxed_slice())
453464
.await?

‎test-data/Abstract$Base.class‎

50 Bytes
Binary file not shown.

‎test-data/Abstract$Derived.class‎

0 Bytes
Binary file not shown.

‎test-data/Abstract.class‎

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
649 Bytes
Binary file not shown.

‎test-data/SuperClass.class‎

119 Bytes
Binary file not shown.

‎test-data/SuperClass.txt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
2
44
test
55
test
6+
leaf
7+
test

‎test-data/src/Abstract.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
class Abstract {
22

33
static abstract class Base {
4+
Base() {}
5+
6+
Base(int value) {}
7+
48
abstract void test();
59
}
610

0 commit comments

Comments
 (0)