| /* |
| * 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; |
| } |
| } |
| |