Skip to content

Commit 0d270c0

Browse files
committed
svm: use reflection in VMError to avoid dependency on JVMCI
1 parent 14b87a0 commit 0d270c0

2 files changed

Lines changed: 70 additions & 20 deletions

File tree

  • substratevm

substratevm/mx.substratevm/suite.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,11 +1397,6 @@
13971397
"sdk:NATIVEIMAGE",
13981398
"sdk:COLLECTIONS",
13991399
],
1400-
"requiresConcealed" : {
1401-
"jdk.internal.vm.ci" : [
1402-
"jdk.vm.ci.meta",
1403-
],
1404-
},
14051400
"checkstyle": "com.oracle.svm.core",
14061401
"javaCompliance" : "21+",
14071402
"workingSets": "SVM",

substratevm/src/com.oracle.svm.shared/src/com/oracle/svm/shared/util/VMError.java

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@
2424
*/
2525
package com.oracle.svm.shared.util;
2626

27+
import java.lang.reflect.Method;
28+
2729
import org.graalvm.nativeimage.Platform;
2830
import org.graalvm.nativeimage.Platforms;
2931

30-
import jdk.vm.ci.meta.ResolvedJavaField;
31-
import jdk.vm.ci.meta.ResolvedJavaMethod;
32-
import jdk.vm.ci.meta.ResolvedJavaType;
33-
3432
/**
3533
* A collection of static methods for error reporting of fatal error. A fatal error leaves the VM in
3634
* an inconsistent state, so no meaningful recovery is possible.
@@ -62,6 +60,49 @@ public static final class HostedError extends Error {
6260

6361
}
6462

63+
@Platforms(Platform.HOSTED_ONLY.class) //
64+
private static final Class<?> ResolvedJavaType;
65+
@Platforms(Platform.HOSTED_ONLY.class) //
66+
private static final Class<?> ResolvedJavaMethod;
67+
@Platforms(Platform.HOSTED_ONLY.class) //
68+
private static final Class<?> ResolvedJavaField;
69+
@Platforms(Platform.HOSTED_ONLY.class) //
70+
private static final Method ResolvedJavaType_toJavaName;
71+
@Platforms(Platform.HOSTED_ONLY.class) //
72+
private static final Method ResolvedJavaMethod_format;
73+
@Platforms(Platform.HOSTED_ONLY.class) //
74+
private static final Method ResolvedJavaField_format;
75+
76+
static {
77+
Class<?> rjt;
78+
Class<?> rjm;
79+
Class<?> rjf;
80+
Method toJavaName;
81+
Method methodFormat;
82+
Method fieldFormat;
83+
try {
84+
rjt = Class.forName("jdk.vm.ci.meta.ResolvedJavaType");
85+
toJavaName = rjt.getMethod("toJavaName", boolean.class);
86+
rjm = Class.forName("jdk.vm.ci.meta.ResolvedJavaMethod");
87+
methodFormat = rjm.getMethod("format", String.class);
88+
rjf = Class.forName("jdk.vm.ci.meta.ResolvedJavaField");
89+
fieldFormat = rjf.getMethod("format", String.class);
90+
} catch (Throwable t) {
91+
rjt = null;
92+
toJavaName = null;
93+
rjm = null;
94+
methodFormat = null;
95+
rjf = null;
96+
fieldFormat = null;
97+
}
98+
ResolvedJavaType = rjt;
99+
ResolvedJavaMethod = rjm;
100+
ResolvedJavaField = rjf;
101+
ResolvedJavaType_toJavaName = toJavaName;
102+
ResolvedJavaMethod_format = methodFormat;
103+
ResolvedJavaField_format = fieldFormat;
104+
}
105+
65106
public static final String msgShouldNotReachHere = "should not reach here";
66107
public static final String msgShouldNotReachHereSubstitution = msgShouldNotReachHere + ": substitution reached at runtime";
67108
public static final String msgShouldNotReachHereUnexpectedInput = msgShouldNotReachHere + ": unexpected input could not be handled";
@@ -213,31 +254,45 @@ public static RuntimeException unsupportedFeature(String msg) {
213254
/**
214255
* Processes {@code args} to convert selected values to strings.
215256
* <ul>
216-
* <li>A {@link ResolvedJavaType} is converted with {@link ResolvedJavaType#toJavaName}
257+
* <li>A {@code ResolvedJavaType} is converted with {@code ResolvedJavaType#toJavaName}
217258
* {@code (true)}.</li>
218-
* <li>A {@link ResolvedJavaMethod} is converted with {@link ResolvedJavaMethod#format}
259+
* <li>A {@code ResolvedJavaMethod} is converted with {@code ResolvedJavaMethod#format}
219260
* {@code ("%H.%n($p)")}.</li>
220-
* <li>A {@link ResolvedJavaField} is converted with {@link ResolvedJavaField#format}
261+
* <li>A {@code ResolvedJavaField} is converted with {@code ResolvedJavaField#format}
221262
* {@code ("%H.%n")}.</li>
222263
* </ul>
223264
* All other values are copied to the returned array unmodified.
224265
*
266+
* @implNote This method uses reflection instead of direct references to JVMCI types to avoid a
267+
* source level dependency on JVMCI.
268+
*
225269
* @param args arguments to process
226270
* @return a copy of {@code args} with certain values converted to strings as described above
227271
*/
228272
public static Object[] formatArguments(Object... args) {
273+
if (args == null) {
274+
return new Object[0];
275+
}
229276
Object[] newArgs = new Object[args.length];
277+
230278
for (int i = 0; i < args.length; i++) {
231279
Object arg = args[i];
232-
if (arg instanceof ResolvedJavaType) {
233-
newArgs[i] = ((ResolvedJavaType) arg).toJavaName(true);
234-
} else if (arg instanceof ResolvedJavaMethod) {
235-
newArgs[i] = ((ResolvedJavaMethod) arg).format("%H.%n(%p)");
236-
} else if (arg instanceof ResolvedJavaField) {
237-
newArgs[i] = ((ResolvedJavaField) arg).format("%H.%n");
238-
} else {
239-
newArgs[i] = arg;
280+
if (ResolvedJavaType != null) {
281+
/* If ResolvedJavaType is available, all JVMCI classes must be available. */
282+
try {
283+
if (ResolvedJavaType.isInstance(arg)) {
284+
arg = ResolvedJavaType_toJavaName.invoke(arg, Boolean.TRUE);
285+
} else if (ResolvedJavaMethod.isInstance(arg)) {
286+
arg = ResolvedJavaMethod_format.invoke(arg, "%H.%n(%p)");
287+
} else if (ResolvedJavaField.isInstance(arg)) {
288+
arg = ResolvedJavaField_format.invoke(arg, "%H.%n");
289+
}
290+
} catch (ReflectiveOperationException t) {
291+
// fall through to default case
292+
}
240293
}
294+
// default
295+
newArgs[i] = arg;
241296
}
242297
return newArgs;
243298
}

0 commit comments

Comments
 (0)