Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

access violation when method on superclass has same name #19

Closed
johanvos opened this issue Dec 30, 2020 · 2 comments
Closed

access violation when method on superclass has same name #19

johanvos opened this issue Dec 30, 2020 · 2 comments

Comments

@johanvos
Copy link
Contributor

@johanvos johanvos commented Dec 30, 2020

When a class Bar extends another class Foo, and Bar has a method with the same signature (private void sayHi) as the one om Foo, and when that method is invoked on an instance of Bar, but in a context where a Foo instance is expected, the private method on the subclass (Bar) is called instead of the method on Foo.

The bytecode contains an invokevirtual method to the method on Foo, but the translated javascript code calls the function on the passed instance (of Bar) and invokes that method (e.g. lca0.sayHi() with lca0 an instance of Bar.

The output of the program below is Hi Foo with hotspot/GraalVM, but it is Hi Bar after being converted with bck2brwsr.


package hellofx;
  
public class HelloFX {

    public static void main(String[] args) {
        Bar bar = new Bar();
        Foo.Helper.sayHello(bar);
    }
}

class Foo {
    static class Helper {
        public static void sayHello(Foo f) {
            f.sayHi();
        }
    }

    private void sayHi() {
        System.err.println("Hi Foo");
    }
}

class Bar extends Foo {

    private void sayHi() {
        System.err.println("Hi Bar");
    }
}
@johanvos johanvos changed the title access violation when methods on superclass has same name access violation when method on superclass has same name Dec 30, 2020
@jtulach
Copy link
Owner

@jtulach jtulach commented Apr 9, 2021

Hello Johan, finally I sit down and wrote a test case 844c9df - however, it is passing without any issues. Even if I modify it to exactly mimic your code, it still works:

diff --git a/rt/vm/src/test/java/org/apidesign/vm4brwsr/HelloFX.java b/rt/vm/src/test/java/org/apidesign/vm4brwsr/HelloFX.java
new file mode 100644
index 00000000..218042f8
--- /dev/null
+++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/HelloFX.java
@@ -0,0 +1,30 @@
+package org.apidesign.vm4brwsr;
+  
+public class HelloFX {
+    static StringBuilder sb = new StringBuilder();
+
+    public static String hello() {
+        Bar bar = new Bar();
+        Foo.Helper.sayHello(bar);
+        return sb.toString();
+    }
+}
+
+class Foo {
+    static class Helper {
+        public static void sayHello(Foo f) {
+            f.sayHi();
+        }
+    }
+
+    private void sayHi() {
+        HelloFX.sb.append("Hi Foo");
+    }
+}
+
+class Bar extends Foo {
+
+    private void sayHi() {
+        HelloFX.sb.append("Hi Bar");
+    }
+}
diff --git a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java
index ca8d2398..3f1163de 100644
--- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java
+++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java
@@ -173,4 +173,8 @@ public class Instance {
     private String sayHi() {
         return "Hi Instance!";
     }
+    
+    public static String helloFX() {
+        return HelloFX.hello();
+    }
 }
diff --git a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java b/rt/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java
index ea1932c2..016d62c9 100644
--- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java
+++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java
@@ -162,6 +162,14 @@ public class InstanceTest {
         );
     }
 
+    @Test public void helloFX() throws Exception {
+        assertExec(
+            "Calls private method properly",
+            Instance.class, "helloFX__Ljava_lang_String_2",
+            "Hi Foo"
+        );
+    }
+
     @Test public void hiInstance() throws Exception {
         assertExec(
             "Calls Instance private method",

I can only assume the problem is in the way you compile from Java to bytecode - there has been a change in the way access methods are compiled by JEP-181 and that may be root cause of your problem. Consider compiling with 1.8 as target and the problem shall go away.

@jtulach jtulach closed this as completed Apr 9, 2021
@jtulach jtulach reopened this Jul 9, 2021
@jtulach
Copy link
Owner

@jtulach jtulach commented Jul 9, 2021

Fixed by 615631f in forthcoming version of Bck2Brwsr.

@jtulach jtulach closed this as completed Jul 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants