Skip to content

Commit 2a2fa13

Browse files
committed
8255449: Improve the exception message of MethodHandles::permuteArguments
Reviewed-by: chegar, mchung
1 parent 2a50c3f commit 2a2fa13

File tree

2 files changed

+75
-16
lines changed

2 files changed

+75
-16
lines changed

src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4739,23 +4739,24 @@ static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodTy
47394739
if (newType.returnType() != oldType.returnType())
47404740
throw newIllegalArgumentException("return types do not match",
47414741
oldType, newType);
4742-
if (reorder.length == oldType.parameterCount()) {
4743-
int limit = newType.parameterCount();
4744-
boolean bad = false;
4745-
for (int j = 0; j < reorder.length; j++) {
4746-
int i = reorder[j];
4747-
if (i < 0 || i >= limit) {
4748-
bad = true; break;
4749-
}
4750-
Class<?> src = newType.parameterType(i);
4751-
Class<?> dst = oldType.parameterType(j);
4752-
if (src != dst)
4753-
throw newIllegalArgumentException("parameter types do not match after reorder",
4754-
oldType, newType);
4742+
if (reorder.length != oldType.parameterCount())
4743+
throw newIllegalArgumentException("old type parameter count and reorder array length do not match",
4744+
oldType, Arrays.toString(reorder));
4745+
4746+
int limit = newType.parameterCount();
4747+
for (int j = 0; j < reorder.length; j++) {
4748+
int i = reorder[j];
4749+
if (i < 0 || i >= limit) {
4750+
throw newIllegalArgumentException("index is out of bounds for new type",
4751+
i, newType);
47554752
}
4756-
if (!bad) return true;
4753+
Class<?> src = newType.parameterType(i);
4754+
Class<?> dst = oldType.parameterType(j);
4755+
if (src != dst)
4756+
throw newIllegalArgumentException("parameter types do not match after reorder",
4757+
oldType, newType);
47574758
}
4758-
throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
4759+
return true;
47594760
}
47604761

47614762
/**

test/jdk/java/lang/invoke/MethodHandlesPermuteArgumentsTest.java

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
import static org.junit.Assert.*;
4646

47-
public class MethodHandlesPermuteArgumentsTest extends MethodHandlesTest {
47+
public class MethodHandlesPermuteArgumentsTest extends test.java.lang.invoke.MethodHandlesTest {
4848

4949
@Test // SLOW
5050
public void testPermuteArguments() throws Throwable {
@@ -58,6 +58,11 @@ public void testPermuteArguments0() throws Throwable {
5858
if (CAN_TEST_LIGHTLY) return;
5959
testPermuteArguments(4, Integer.class, 2, String.class, 0);
6060
testPermuteArguments(6, Integer.class, 0, null, 30);
61+
62+
testBadReorderArrayLength();
63+
testBadReorderIndex();
64+
testReturnTypeMismatch();
65+
testReorderTypeMismatch();
6166
}
6267

6368
public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
@@ -191,4 +196,57 @@ void testPermuteArguments(Object[] args, Class<?>[] types, int[] reorder) throws
191196
}
192197
assertEquals(expected, result);
193198
}
199+
200+
public void testBadReorderArrayLength() throws Throwable {
201+
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
202+
MethodType newType = MethodType.methodType(void.class, int.class, String.class);
203+
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 1),
204+
IllegalArgumentException.class, ".*old type parameter count and reorder array length do not match.*");
205+
}
206+
207+
public void testBadReorderIndex() throws Throwable {
208+
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
209+
MethodType newType = MethodType.methodType(void.class, int.class, String.class);
210+
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 2),
211+
IllegalArgumentException.class, ".*index is out of bounds for new type.*");
212+
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, -1),
213+
IllegalArgumentException.class, ".*index is out of bounds for new type.*");
214+
}
215+
216+
public void testReturnTypeMismatch() throws Throwable {
217+
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
218+
MethodType newType = MethodType.methodType(int.class, int.class, String.class);
219+
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 1),
220+
IllegalArgumentException.class, ".*return types do not match.*");
221+
}
222+
223+
public void testReorderTypeMismatch() throws Throwable {
224+
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
225+
MethodType newType = MethodType.methodType(void.class, double.class, String.class);
226+
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 1),
227+
IllegalArgumentException.class, ".*parameter types do not match after reorder.*");
228+
}
229+
230+
private interface RunnableX {
231+
void run() throws Throwable;
232+
}
233+
234+
private static void assertThrows(RunnableX r, Class<?> exceptionClass, String messagePattern) throws Throwable {
235+
try {
236+
r.run();
237+
fail("Exception expected");
238+
} catch (Throwable e) {
239+
if (exceptionClass.isInstance(e)) {
240+
assertMatches(e.getMessage(), messagePattern);
241+
} else {
242+
throw e;
243+
}
244+
}
245+
}
246+
247+
private static void assertMatches(String str, String pattern) {
248+
if (!str.matches(pattern)) {
249+
throw new AssertionError("'" + str + "' did not match the pattern '" + pattern + "'.");
250+
}
251+
}
194252
}

0 commit comments

Comments
 (0)