diff options
author | 2017-01-19 20:42:23 +0000 | |
---|---|---|
committer | 2017-01-24 17:15:01 +0000 | |
commit | c5889ce65ef7d31d4f0fe7be8f7f7f45948c5b5b (patch) | |
tree | 5ae5f194ed3f8aa8eb6cec23f3262d5c2b3807fa | |
parent | d8981ee26340c46b608fdff2cdf294b2f7d4afce (diff) |
MethodHandles: Support and tests for invokeWithArguments.
Tracks libcore change a8cf0bffdb9e9cf031efd0d3c8b5645d45963562.
Test: make test-art-host
Change-Id: I65fbf3a82b629585324c477bdce6dabd63ae408e
-rw-r--r-- | runtime/class_linker_test.cc | 2 | ||||
-rw-r--r-- | runtime/mirror/method_handle_impl.h | 4 | ||||
-rw-r--r-- | test/957-methodhandle-transforms/expected.txt | 3 | ||||
-rw-r--r-- | test/957-methodhandle-transforms/src/Main.java | 29 |
4 files changed, 37 insertions, 1 deletions
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 7b6c0dc510..c3115420c7 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -743,6 +743,8 @@ struct MethodHandleImplOffsets : public CheckOffsets<mirror::MethodHandleImpl> { MethodHandleImplOffsets() : CheckOffsets<mirror::MethodHandleImpl>( false, "Ljava/lang/invoke/MethodHandle;") { addOffset(OFFSETOF_MEMBER(mirror::MethodHandleImpl, art_field_or_method_), "artFieldOrMethod"); + addOffset(OFFSETOF_MEMBER(mirror::MethodHandleImpl, cached_spread_invoker_), + "cachedSpreadInvoker"); addOffset(OFFSETOF_MEMBER(mirror::MethodHandleImpl, handle_kind_), "handleKind"); addOffset(OFFSETOF_MEMBER(mirror::MethodHandleImpl, nominal_type_), "nominalType"); addOffset(OFFSETOF_MEMBER(mirror::MethodHandleImpl, method_type_), "type"); diff --git a/runtime/mirror/method_handle_impl.h b/runtime/mirror/method_handle_impl.h index abe999a5ac..2f26a22ca8 100644 --- a/runtime/mirror/method_handle_impl.h +++ b/runtime/mirror/method_handle_impl.h @@ -84,10 +84,12 @@ class MANAGED MethodHandle : public Object { static mirror::Class* StaticClass() REQUIRES_SHARED(Locks::mutator_lock_); private: + // NOTE: cached_spread_invoker_ isn't used by the runtime. + HeapReference<mirror::MethodHandle> cached_spread_invoker_; HeapReference<mirror::MethodType> nominal_type_; HeapReference<mirror::MethodType> method_type_; - uint64_t art_field_or_method_; uint32_t handle_kind_; + uint64_t art_field_or_method_; private: static MemberOffset NominalTypeOffset() { diff --git a/test/957-methodhandle-transforms/expected.txt b/test/957-methodhandle-transforms/expected.txt index 154051f847..383ccd9606 100644 --- a/test/957-methodhandle-transforms/expected.txt +++ b/test/957-methodhandle-transforms/expected.txt @@ -47,3 +47,6 @@ a: a, b:1.0, c: 2.0, d: 3.0 a: a, b:1.0, c: 2.0, d: 3.0 a: a, b:1.0, c: 2.0 a: a, b:1.0, c: 2.0 +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:43 diff --git a/test/957-methodhandle-transforms/src/Main.java b/test/957-methodhandle-transforms/src/Main.java index 3271108995..d0bd816837 100644 --- a/test/957-methodhandle-transforms/src/Main.java +++ b/test/957-methodhandle-transforms/src/Main.java @@ -36,6 +36,7 @@ public class Main { testInvokers(); testSpreaders_reference(); testSpreaders_primitive(); + testInvokeWithArguments(); } public static void testThrowException() throws Throwable { @@ -1223,6 +1224,34 @@ public class Main { assertEquals(51, ret); } + public static void testInvokeWithArguments() throws Throwable { + MethodType methodType = MethodType.methodType(int.class, + new Class<?>[] { String.class, String.class, String.class }); + MethodHandle handle = MethodHandles.lookup().findStatic( + Main.class, "spreadReferences", methodType); + + Object ret = handle.invokeWithArguments(new Object[] { "a", "b", "c"}); + assertEquals(42, (int) ret); + handle.invokeWithArguments(new String[] { "a", "b", "c" }); + assertEquals(42, (int) ret); + + // Pass in an array that's too small. Should throw an IAE. + try { + handle.invokeWithArguments(new Object[] { "a", "b" }); + fail(); + } catch (IllegalArgumentException expected) { + } + + // Test implicit unboxing. + MethodType methodType2 = MethodType.methodType(int.class, + new Class<?>[] { String.class, int.class }); + MethodHandle handle2 = MethodHandles.lookup().findStatic( + Main.class, "spreadReferences_Unbox", methodType2); + + ret = (int) handle2.invokeWithArguments(new Object[] { "a", 43 }); + assertEquals(43, (int) ret); + } + public static void fail() { System.out.println("FAIL"); Thread.dumpStack(); |