Function.call() can invoke a different function depending on its parameter if the parameter is an instance of a Java class and the function is overloaded in a child of the class

UNCONFIRMED
Unassigned

Status

UNCONFIRMED
11 years ago
4 years ago

People

(Reporter: ksniloc, Unassigned)

Tracking

Details

Attachments

(1 attachment)

(Reporter)

Description

11 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.3) Gecko/20070417 Fedora/2.0.0.3-4.fc7 Firefox/2.0.0.3
Build Identifier: Rhino1_6R5

If a JavaScript script is being compiled with the -extends parameter, it seems to be impossible to call the parent's version of a method that is being overridden because calling Function.call(x) calls a different function depending on the value of x, even though it should call the function represented by the object every time. The code sample makes the meaning of this more clear.

Reproducible: Always

Steps to Reproduce:
Extract the attached archive somewhere and then try:

javac Parent.java
java -cp js.jar:. org.mozilla.javascript.tools.jsc.Main -extends Parent child.js
java -cp js.jar:. Parent

Of course, you may need to alter the path to js.jar. These instructions are also present in the 'readme' file in the archive.
Actual Results:  
Hello, world from the parent's function!
Hello, world from the child's function!


Expected Results:  
Since Function.call() is called on the same function object both times, I expect that the same function be called, and the expected result is:

Hello, world from the parent's function!
Hello, world from the parent's function!

As mentioned above, this bug seems to make it impossible to call the parent's version of a method in a JavaScript script implementing a Java class.
(Reporter)

Comment 1

11 years ago
Created attachment 270643 [details]
Code that demonstrates the error

Instructions for using the contents of the archive are found in the 'readme' file and also in the bug report itself.
(Reporter)

Comment 2

11 years ago
Further research shows that this will probably be difficult to fix in a simple manner because the JDK documentation specifies that when calling the java.lang.reflect.Method.invoke() method (see http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Method.html#invoke(java.lang.Object,%20java.lang.Object[])), "overriding based on the runtime type of the target object will occur".

One way to fix it might be to add add hidden methods to compiled Java classes that call overridden parent methods. For example, in this case, the compiler might add the bytecode equivalent of

public void __hidden__func() {
    super.func();
}

to the class. Then the implementation of Function.call could look for the presence of this method when trying to call a parent method if the class was implemented by JavaScript. Another possibility might be to accept references to this.parent in code going through the compiler and compile this to call the parent method through however 'super' is implemented in .class files.
(Reporter)

Updated

11 years ago
OS: Linux → All

Comment 3

4 years ago
Hi, I would like to work on this bug. It would be my first time so please guide me.
You need to log in before you can comment on or make changes to this bug.