blob: 7895895e569aed1b55bdaafac6cd6ffb9caa7b76 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package libcore.java.lang.invoke;
import junit.framework.TestCase;
import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.invoke.MutableCallSite;
import java.lang.invoke.VolatileCallSite;
import java.lang.invoke.WrongMethodTypeException;
import static java.lang.invoke.MethodHandles.Lookup.*;
public class CallSitesTest extends TestCase {
public void test_ConstantCallSiteConstructorNullMethodHandle() throws Throwable {
try {
ConstantCallSite site = new ConstantCallSite((MethodHandle) null);
fail();
} catch (NullPointerException e) {
}
}
private static MethodHandle methodHandleForAdd2() throws Throwable {
final MethodType mt = MethodType.methodType(int.class, int.class, int.class);
return MethodHandles.lookup().findStatic(CallSitesTest.class, "add2", mt);
}
public void test_ConstantCallSite() throws Throwable {
final MethodHandle mh = methodHandleForAdd2();
ConstantCallSite site = new ConstantCallSite(mh);
int n = (int) site.dynamicInvoker().invokeExact(7, 37);
assertEquals(44, n);
try {
site.setTarget(mh);
fail();
} catch (UnsupportedOperationException e) {
}
}
public void test_MutableCallSiteConstructorNullMethodType() throws Throwable {
try {
MutableCallSite callSite = new MutableCallSite((MethodType) null);
fail();
} catch (NullPointerException e) {
}
}
public void test_MutableCallSiteConstructorNullMethodHandle() throws Throwable {
try {
MutableCallSite callSite = new MutableCallSite((MethodHandle) null);
fail();
} catch (NullPointerException e) {
}
}
public void test_MutableCallsiteNoMethodHandle() throws Throwable {
try {
MutableCallSite callSite =
new MutableCallSite(MethodType.methodType(int.class, int.class, int.class));
int result = (int) callSite.getTarget().invokeExact(1, 2);
fail();
} catch (IllegalStateException e) {
}
}
public void test_MutableCallSite() throws Throwable {
final MethodHandle mh = methodHandleForAdd2();
final MutableCallSite site = new MutableCallSite(mh);
// Invocation test
int n = (int) site.getTarget().invokeExact(7, 37);
assertEquals(44, n);
// setTarget() tests
try {
final MethodType mt_add3 =
MethodType.methodType(int.class, int.class, int.class, int.class);
final MethodHandle mh_add3 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "add3", mt_add3);
site.setTarget(mh_add3);
fail();
} catch (WrongMethodTypeException e) {
}
try {
site.setTarget(null);
fail();
} catch (NullPointerException e) {
}
final MethodHandle mh_sub2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "sub2",
MethodType.methodType(int.class, int.class, int.class));
site.setTarget(mh_sub2);
n = (int) site.getTarget().invokeExact(7, 37);
assertEquals(-30, n);
}
public void test_VolatileCallSiteConstructorNullMethodType() throws Throwable {
try {
VolatileCallSite vc = new VolatileCallSite((MethodType) null);
fail();
} catch (NullPointerException e) {
}
}
public void test_VolatileCallSiteConstructorNullMethodHandle() throws Throwable {
try {
VolatileCallSite vc = new VolatileCallSite((MethodHandle) null);
fail();
} catch (NullPointerException e) {
}
}
public void test_VolatileCallsiteNoMethodHandle() throws Throwable {
try {
VolatileCallSite vc =
new VolatileCallSite(MethodType.methodType(int.class, int.class, int.class));
int result = (int) vc.getTarget().invokeExact(1, 2);
fail();
} catch (IllegalStateException e) {
}
}
public void test_VolatileCallSite() throws Throwable {
final MethodHandle mh = methodHandleForAdd2();
final VolatileCallSite site = new VolatileCallSite(mh);
// Invocation test
int n = (int) site.getTarget().invokeExact(7, 37);
assertEquals(44, n);
// setTarget() tests
try {
final MethodType mt_add3 =
MethodType.methodType(int.class, int.class, int.class, int.class);
final MethodHandle mh_add3 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "add3", mt_add3);
site.setTarget(mh_add3);
fail();
} catch (WrongMethodTypeException e) {
}
try {
site.setTarget(null);
fail();
} catch (NullPointerException e) {
}
// One last invocation test
final MethodHandle mh_sub2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "sub2",
MethodType.methodType(int.class, int.class, int.class));
site.setTarget(mh_sub2);
n = (int) site.getTarget().invokeExact(7, 37);
assertEquals(-30, n);
}
public void test_EarlyBoundMutableCallSite() throws Throwable {
final MethodType type = MethodType.methodType(int.class, int.class, int.class);
final MethodHandle add2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "add2", type);
MutableCallSite site = new MutableCallSite(type);
commonMutableCallSitesTest(site, add2);
}
public void test_EarlyBoundVolatileCallSite() throws Throwable {
final MethodType type = MethodType.methodType(int.class, int.class, int.class);
final MethodHandle add2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "add2", type);
VolatileCallSite site = new VolatileCallSite(type);
commonMutableCallSitesTest(site, add2);
}
public void test_LateBoundMutableCallSite() throws Throwable {
final MethodType type = MethodType.methodType(int.class, int.class, int.class);
MutableCallSite site = new MutableCallSite(type);
assertEquals(type, site.type());
try {
int fake = (int) site.getTarget().invokeExact(1, 1);
fail();
} catch (IllegalStateException e) {
assertEquals("uninitialized call site", e.getMessage());
}
final MethodHandle add2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "add2", type);
site.setTarget(add2);
commonMutableCallSitesTest(site, add2);
}
public void test_LateBoundVolatileCallSite() throws Throwable {
final MethodType type = MethodType.methodType(int.class, int.class, int.class);
VolatileCallSite site = new VolatileCallSite(type);
assertEquals(type, site.type());
try {
int fake = (int) site.getTarget().invokeExact(1, 1);
fail();
} catch (IllegalStateException e) {
assertEquals("uninitialized call site", e.getMessage());
}
final MethodHandle add2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "add2", type);
site.setTarget(add2);
commonMutableCallSitesTest(site, add2);
}
private static void commonMutableCallSitesTest(CallSite site,
MethodHandle firstTarget) throws Throwable {
site.setTarget(firstTarget);
site.setTarget(firstTarget);
int x = (int) firstTarget.invokeExact(2, 6);
assertEquals(8, x);
int y = (int) site.getTarget().invokeExact(2, 6);
assertEquals(8, y);
int z = (int) site.dynamicInvoker().invokeExact(2, 6);
assertEquals(8, z);
try {
site.setTarget(null);
fail();
} catch (NullPointerException e) {
}
final MethodHandle other = MethodHandles.lookup().findStatic(
CallSitesTest.class, "add3",
MethodType.methodType(int.class, int.class, int.class, int.class));
try {
site.setTarget(other);
fail();
} catch (WrongMethodTypeException e) {
}
assertEquals(firstTarget, site.getTarget());
final MethodHandle sub2 =
MethodHandles.lookup().findStatic(CallSitesTest.class, "sub2", firstTarget.type());
site.setTarget(sub2);
assertEquals(sub2, site.getTarget());
assertEquals(100, (int) site.dynamicInvoker().invokeExact(147, 47));
}
private static int add2(int x, int y) {
return x + y;
}
private static int add3(int x, int y, int z) {
return x + y + z;
}
private static int sub2(int x, int y) {
return x - y;
}
}