Skip to content

Commit

Permalink
When InterfaceAdapter is used, the wrong thisObj is used
Browse files Browse the repository at this point in the history
  • Loading branch information
rPraml committed Feb 28, 2024
1 parent 6ec1085 commit 893a8f0
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 2 deletions.
3 changes: 1 addition & 2 deletions src/org/mozilla/javascript/InterfaceAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,8 @@ Object invokeImpl(
}
}
}
Scriptable thisObj = wf.wrapAsJavaObject(cx, topScope, thisObject, null);

Object result = function.call(cx, topScope, thisObj, args);
Object result = function.call(cx, topScope, (Scriptable) target, args);
Class<?> javaResultType = method.getReturnType();
if (javaResultType == Void.TYPE) {
result = null;
Expand Down
111 changes: 111 additions & 0 deletions testsrc/org/mozilla/javascript/tests/JavaAdapterInvokeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.mozilla.javascript.tests;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;

public class JavaAdapterInvokeTest {
Context cx = null;
Scriptable topScope = null;

@Before
public void enterContext() {
cx = Context.enter();
cx.setOptimizationLevel(-1);
topScope = cx.initStandardObjects();
}

@After
public void exitContext() {
Context.exit();
}

public interface AdapterInterface {
int m1(int i);

int m2();
}

public static class AdapterClass {
private AdapterInterface adapter;

public AdapterClass(AdapterInterface adapter) {
this.adapter = adapter;
}

public int doIt(int i) {
return this.adapter.m1(i) + this.adapter.m2();
}
}

@Test
public void testInvoke() throws NoSuchMethodException {
String testCode =
"'use strict'\n"
+ "var impl = {"
+ " m1: function(i) { return i + 1 },\n"
+ " m2: function() { return 7 }\n"
+ "}\n"
+ "adapter = new Packages."
+ AdapterClass.class.getName()
+ "(impl)\n"
+ "adapter.doIt(42)";

Number result = (Number) cx.evaluateString(topScope, testCode, "", 1, null);
Assert.assertEquals(50, result.intValue());
}

@Test
public void testInvokeWithPrototype() throws NoSuchMethodException {
String testCode =
"'use strict'\n"
+ "function Obj() {}\n"
+ "Obj.prototype.m1 = function(i) { return i + 1 }\n"
+ "Obj.prototype.m2 = function() { return 7 }\n"
+ "var impl = new Obj()\n"
+ "adapter = new Packages."
+ AdapterClass.class.getName()
+ "(impl)\n"
+ "adapter.doIt(42)";

Number result = (Number) cx.evaluateString(topScope, testCode, "", 1, null);
Assert.assertEquals(50, result.intValue());
}

@Test
public void testInvokeWithPrototypeAndCtor() throws NoSuchMethodException {
String testCode =
"'use strict'\n"
+ "function Obj() { this.myObj = {one: 1} }\n"
+ "Obj.prototype.m1 = function(i) { return i + this.myObj.one }\n"
+ "Obj.prototype.m2 = function() { return 7 }\n"
+ "var impl = new Obj()\n"
+ "adapter = new Packages."
+ AdapterClass.class.getName()
+ "(impl)\n"
+ "adapter.doIt(42)";

Number result = (Number) cx.evaluateString(topScope, testCode, "", 1, null);
Assert.assertEquals(50, result.intValue());
}

@Test
public void testInvokeJsOnly() throws NoSuchMethodException {
String testCode =
"'use strict'\n"
+ "function Obj() { this.myObj = {one: 1} }\n"
+ "Obj.prototype.m1 = function(i) { return i + this.myObj.one }\n"
+ "Obj.prototype.m2 = function() { return 7 }\n"
+ "function Adapter(adapter) { this.adapter = adapter }\n"
+ "Adapter.prototype.doIt = function(i) { return this.adapter.m1(i) + this.adapter.m2() }\n"
+ "var impl = new Obj()\n"
+ "adapter = new Adapter(impl)\n"
+ "adapter.doIt(42)";

Number result = (Number) cx.evaluateString(topScope, testCode, "", 1, null);
Assert.assertEquals(50, result.intValue());
}
}

0 comments on commit 893a8f0

Please sign in to comment.