Skip to content

Commit a86b6f6

Browse files
author
Mandy Chung
committed
8299183: Invokers.checkExactType passes parameters to create WMTE in opposite order
Reviewed-by: iris, jpai
1 parent 8b0133f commit a86b6f6

File tree

4 files changed

+102
-18
lines changed

4 files changed

+102
-18
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -494,8 +494,7 @@ private static LambdaForm varHandleMethodInvokerHandleForm(MethodType mtype, boo
494494
@Hidden
495495
static MethodHandle checkVarHandleGenericType(VarHandle handle, VarHandle.AccessDescriptor ad) {
496496
if (handle.hasInvokeExactBehavior() && handle.accessModeType(ad.type) != ad.symbolicMethodTypeExact) {
497-
throw new WrongMethodTypeException("expected " + handle.accessModeType(ad.type) + " but found "
498-
+ ad.symbolicMethodTypeExact);
497+
throw newWrongMethodTypeException(handle.accessModeType(ad.type), ad.symbolicMethodTypeExact);
499498
}
500499
// Test for exact match on invoker types
501500
// TODO match with erased types and add cast of return value to lambda form
@@ -518,18 +517,18 @@ static MethodHandle checkVarHandleExactType(VarHandle handle, VarHandle.AccessDe
518517
}
519518

520519
/*non-public*/
521-
static WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
520+
static WrongMethodTypeException newWrongMethodTypeException(MethodType targetType, MethodType callSiteType) {
522521
// FIXME: merge with JVM logic for throwing WMTE
523-
return new WrongMethodTypeException("expected "+expected+" but found "+actual);
522+
return new WrongMethodTypeException("handle's method type " + targetType + " but found " + callSiteType);
524523
}
525524

526525
/** Static definition of MethodHandle.invokeExact checking code. */
527526
@ForceInline
528527
/*non-public*/
529528
static void checkExactType(MethodHandle mh, MethodType expected) {
530-
MethodType actual = mh.type();
531-
if (actual != expected)
532-
throw newWrongMethodTypeException(expected, actual);
529+
MethodType targetType = mh.type();
530+
if (targetType != expected)
531+
throw newWrongMethodTypeException(targetType, expected);
533532
}
534533

535534
/** Static definition of MethodHandle.invokeGeneric checking code.

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -2083,8 +2083,8 @@ boolean checkAccessModeThenIsDirect(VarHandle.AccessDescriptor ad) {
20832083

20842084
@DontInline
20852085
private final void throwWrongMethodTypeException(VarHandle.AccessDescriptor ad) {
2086-
throw new WrongMethodTypeException("expected " + accessModeType(ad.type) + " but found "
2087-
+ ad.symbolicMethodTypeExact);
2086+
throw new WrongMethodTypeException("handle's method type " + accessModeType(ad.type)
2087+
+ " but found " + ad.symbolicMethodTypeExact);
20882088
}
20892089

20902090
@ForceInline

test/jdk/java/lang/invoke/VarHandles/VarHandleTestExact.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public void testExactSet(String fieldBaseName, Class<?> fieldType, boolean ro, O
101101
doTest(vh,
102102
tvh -> tvh.set(w, testValue),
103103
tvh -> setter.set(tvh, w, testValue),
104-
".*\\Qexpected (Widget," + fieldType.getSimpleName() + ")void \\E.*");
104+
".*\\Qhandle's method type (Widget," + fieldType.getSimpleName() + ")void \\E.*");
105105
}
106106

107107
@Test(dataProvider = "dataObjectAccess")
@@ -115,7 +115,7 @@ public void testExactGet(String fieldBaseName, Class<?> fieldType, boolean ro, O
115115
doTest(vh,
116116
tvh -> tvh.get(w),
117117
tvh -> getter.get(tvh, w),
118-
".*\\Qexpected (Widget)" + fieldType.getSimpleName() + " \\E.*");
118+
".*\\Qhandle's method type (Widget)" + fieldType.getSimpleName() + " \\E.*");
119119
}
120120

121121
@Test(dataProvider = "dataObjectAccess")
@@ -129,7 +129,7 @@ public void testExactSetStatic(String fieldBaseName, Class<?> fieldType, boolean
129129
doTest(vh,
130130
tvh -> tvh.set(testValue),
131131
tvh -> staticSetter.set(tvh, testValue),
132-
".*\\Qexpected (" + fieldType.getSimpleName() + ")void \\E.*");
132+
".*\\Qhandle's method type (" + fieldType.getSimpleName() + ")void \\E.*");
133133
}
134134

135135
@Test(dataProvider = "dataObjectAccess")
@@ -142,7 +142,7 @@ public void testExactGetStatic(String fieldBaseName, Class<?> fieldType, boolean
142142
doTest(vh,
143143
tvh -> tvh.get(),
144144
tvh -> staticGetter.get(tvh),
145-
".*\\Qexpected ()" + fieldType.getSimpleName() + " \\E.*");
145+
".*\\Qhandle's method type ()" + fieldType.getSimpleName() + " \\E.*");
146146
}
147147

148148
@Test(dataProvider = "dataSetArray")
@@ -153,7 +153,7 @@ public void testExactArraySet(Class<?> arrayClass, Object testValue, SetArrayX s
153153
doTest(vh,
154154
tvh -> tvh.set(arr, 0, testValue),
155155
tvh -> setter.set(tvh, arr, testValue),
156-
".*\\Qexpected (" + arrayClass.getSimpleName() + ",int," + arrayClass.componentType().getSimpleName() + ")void \\E.*");
156+
".*\\Qhandle's method type (" + arrayClass.getSimpleName() + ",int," + arrayClass.componentType().getSimpleName() + ")void \\E.*");
157157
}
158158

159159
@Test(dataProvider = "dataSetBuffer")
@@ -164,7 +164,7 @@ public void testExactBufferSet(Class<?> arrayClass, Object testValue, SetBufferX
164164
doTest(vh,
165165
tvh -> tvh.set(buff, 0, testValue),
166166
tvh -> setter.set(tvh, buff, testValue),
167-
".*\\Qexpected (ByteBuffer,int," + arrayClass.componentType().getSimpleName() + ")void \\E.*");
167+
".*\\Qhandle's method type (ByteBuffer,int," + arrayClass.componentType().getSimpleName() + ")void \\E.*");
168168
}
169169

170170
@Test(dataProvider = "dataSetMemorySegment")
@@ -175,7 +175,7 @@ public void testExactSegmentSet(Class<?> carrier, Object testValue, SetSegmentX
175175
doTest(vh,
176176
tvh -> tvh.set(seg, 0L, testValue),
177177
tvh -> setter.set(tvh, seg, 0L, testValue),
178-
".*\\Qexpected (MemorySegment,long," + carrier.getSimpleName() + ")void \\E.*");
178+
".*\\Qhandle's method type (MemorySegment,long," + carrier.getSimpleName() + ")void \\E.*");
179179
}
180180
}
181181

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/* @test 8299183
25+
* @run testng WrongMethodTypeTest
26+
*/
27+
28+
import java.lang.invoke.MethodHandle;
29+
import java.lang.invoke.MethodHandles;
30+
import java.lang.invoke.MethodHandles.Lookup;
31+
import java.lang.invoke.VarHandle;
32+
import java.lang.invoke.WrongMethodTypeException;
33+
34+
import static java.lang.invoke.MethodType.methodType;
35+
36+
import static org.testng.AssertJUnit.*;
37+
38+
import org.testng.annotations.*;
39+
40+
public class WrongMethodTypeTest {
41+
static final Lookup LOOKUP = MethodHandles.lookup();
42+
43+
@Test
44+
public void checkExactType() throws Throwable {
45+
String expectedMessage = "handle's method type (int)int but found ()boolean";
46+
try {
47+
MethodHandle mh = LOOKUP.findStatic(WrongMethodTypeTest.class, "m", methodType(int.class, int.class));
48+
boolean b = (boolean)mh.invokeExact();
49+
fail("Expected WrongMethodTypeException");
50+
} catch (WrongMethodTypeException ex) {
51+
assertEquals(expectedMessage, ex.getMessage());
52+
}
53+
}
54+
55+
@Test
56+
public void checkAccessModeInvokeExact() throws Throwable {
57+
String expectedMessage = "handle's method type ()int but found ()Void";
58+
VarHandle vh = LOOKUP.findStaticVarHandle(WrongMethodTypeTest.class, "x", int.class)
59+
.withInvokeExactBehavior();
60+
try {
61+
Void o = (Void) vh.get();
62+
} catch (WrongMethodTypeException ex) {
63+
assertEquals(expectedMessage, ex.getMessage());
64+
}
65+
}
66+
67+
@Test
68+
public void checkVarHandleInvokeExact() throws Throwable {
69+
String expectedMessage = "handle's method type (WrongMethodTypeTest)boolean but found (WrongMethodTypeTest)int";
70+
VarHandle vh = LOOKUP.findVarHandle(WrongMethodTypeTest.class, "y", boolean.class)
71+
.withInvokeExactBehavior();
72+
try {
73+
int o = (int) vh.get(new WrongMethodTypeTest());
74+
} catch (WrongMethodTypeException ex) {
75+
assertEquals(expectedMessage, ex.getMessage());
76+
}
77+
}
78+
79+
static int m(int x) {
80+
return x;
81+
}
82+
83+
static int x = 200;
84+
boolean y = false;
85+
}

0 commit comments

Comments
 (0)