Skip to content

Commit 6a06def

Browse files
committed
[GR-35724] HotSpot to Native calls pass exception using ForeignException.
PullRequest: graal/11258
2 parents 335ba6d + 7ff3395 commit 6a06def

31 files changed

+1435
-1086
lines changed

compiler/docs/NativeBridgeProcessor.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -235,17 +235,22 @@ The `Complex` type is unknown to the annotation processor. We need to provide a
235235
final class ComplexMarshaller implements BinaryMarshaller<Complex> {
236236

237237
@Override
238-
public Complex read(BinaryInput input) throws IOException {
238+
public Complex read(BinaryInput input) {
239239
int re = input.readInt();
240240
int img = input.readInt();
241241
return new Complex(re, img);
242242
}
243243

244244
@Override
245-
public void write(BinaryOutput output, Complex complex) throws IOException {
245+
public void write(BinaryOutput output, Complex complex) {
246246
output.writeInt(complex.re);
247247
output.writeInt(complex.img);
248248
}
249+
250+
@Override
251+
public int inferSize(Complex complex) {
252+
return Integer.BYTES * 2;
253+
}
249254
}
250255
```
251256

compiler/src/org.graalvm.jniutils/src/org/graalvm/jniutils/JNIExceptionWrapper.java

+41-10
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public static JThrowable createHSException(JNIEnv env, Throwable original) {
220220
StackTraceElement[] mergedStack = mergeStackTraces(hsStack, nativeStack,
221221
hasSameExceptionType ? 0 : 1, // exception with same exception
222222
// type has no factory method
223-
0, false);
223+
getIndexOfPropagateJNIExceptionFrame(nativeStack), false);
224224
hsThrowable = updateStackTrace(env, hsThrowable, mergedStack);
225225
}
226226
}
@@ -345,6 +345,25 @@ public void handleException(ExceptionHandlerContext context) {
345345
void handleException(ExceptionHandlerContext context);
346346
}
347347

348+
public static StackTraceElement[] mergeStackTraces(
349+
StackTraceElement[] hotSpotStackTrace,
350+
StackTraceElement[] nativeStackTrace,
351+
boolean originatedInHotSpot) {
352+
if (originatedInHotSpot) {
353+
if (containsHotSpotCall(hotSpotStackTrace)) {
354+
// Already merged
355+
return hotSpotStackTrace;
356+
}
357+
} else {
358+
if (containsHotSpotCall(nativeStackTrace)) {
359+
// Already merged
360+
return nativeStackTrace;
361+
}
362+
}
363+
return mergeStackTraces(hotSpotStackTrace, nativeStackTrace, originatedInHotSpot ? 0 : getIndexOfTransitionFromHotSpotFrame(hotSpotStackTrace),
364+
getIndexOfPropagateJNIExceptionFrame(nativeStackTrace), originatedInHotSpot);
365+
}
366+
348367
/**
349368
* Merges {@code hotSpotStackTrace} with {@code nativeStackTrace}.
350369
*
@@ -390,7 +409,7 @@ private static StackTraceElement[] mergeStackTraces(
390409
* Gets the stack trace from a JNI exception.
391410
*
392411
* @param env the {@link JNIEnv}
393-
* @param throwableHandle the JNI exception to get the stack trace from
412+
* @param throwableHandle the JNI exception to get the stack trace from.
394413
* @return the stack trace
395414
*/
396415
private static StackTraceElement[] getJNIExceptionStackTrace(JNIEnv env, JObject throwableHandle) {
@@ -480,33 +499,45 @@ private static int getIndexOfPropagateJNIExceptionFrame(StackTraceElement[] stac
480499
return 0;
481500
}
482501

502+
/**
503+
* Gets the index of the first frame denoting the native method call.
504+
*
505+
* @returns {@code 0} if no caller found
506+
*/
507+
private static int getIndexOfTransitionFromHotSpotFrame(StackTraceElement[] stackTrace) {
508+
for (int i = 0; i < stackTrace.length; i++) {
509+
if (stackTrace[i].isNativeMethod()) {
510+
return i;
511+
}
512+
}
513+
return 0;
514+
}
515+
483516
private static boolean isStackFrame(StackTraceElement stackTraceElement, Class<?> clazz, String methodName) {
484517
return clazz.getName().equals(stackTraceElement.getClassName()) && methodName.equals(stackTraceElement.getMethodName());
485518
}
486519

487-
private static <T extends JObject> T createExceptionOfSameType(JNIEnv env, Throwable original) {
488-
WordFactory.nullPointer();
489-
String className = original.getClass().getTypeName();
520+
private static JThrowable createExceptionOfSameType(JNIEnv env, Throwable original) {
521+
Class<? extends Throwable> originalType = original.getClass();
522+
String className = originalType.getTypeName();
490523
JClass exceptionClass = JNIUtil.findClass(env, WordFactory.nullPointer(), getBinaryName(className), false);
491524
if (exceptionClass.isNonNull()) {
492525
JNIMethod constructor = JNIMethod.findMethod(env, exceptionClass, false, false, "<init>", encodeMethodSignature(void.class, String.class));
493526
if (constructor != null) {
494527
JNI.JValue args = StackValue.get(1, JNI.JValue.class);
495528
args.addressOf(0).setJObject(createHSString(env, original.getMessage()));
496-
T res = HotSpotCalls.getDefault().callNewObject(env, exceptionClass, constructor, args);
497-
return res;
529+
return HotSpotCalls.getDefault().callNewObject(env, exceptionClass, constructor, args);
498530
}
499531
constructor = JNIMethod.findMethod(env, exceptionClass, false, false, "<init>", encodeMethodSignature(void.class));
500532
if (constructor != null) {
501-
T res = HotSpotCalls.getDefault().callNewObject(env, exceptionClass, constructor, WordFactory.nullPointer());
502-
return res;
533+
return HotSpotCalls.getDefault().callNewObject(env, exceptionClass, constructor, WordFactory.nullPointer());
503534
}
504535
}
505536
return WordFactory.nullPointer();
506537
}
507538

508539
// JNI calls
509-
private static <T extends JObject> T callCreateException(JNIEnv env, JObject p0) {
540+
private static JThrowable callCreateException(JNIEnv env, JObject p0) {
510541
JNI.JValue args = StackValue.get(1, JNI.JValue.class);
511542
args.addressOf(0).setJObject(p0);
512543
return HotSpotCalls.getDefault().callStaticJObject(env, getHotSpotEntryPoints(env), CreateException.resolve(env), args);

compiler/src/org.graalvm.nativebridge/src/org/graalvm/nativebridge/ExceptionHandler.java renamed to compiler/src/org.graalvm.nativebridge.processor.test/src/org/graalvm/nativebridge/processor/test/CustomMarshallerService.java

+9-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 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
@@ -22,19 +22,14 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package org.graalvm.nativebridge;
25+
package org.graalvm.nativebridge.processor.test;
2626

27-
import java.lang.annotation.ElementType;
28-
import java.lang.annotation.Retention;
29-
import java.lang.annotation.RetentionPolicy;
30-
import java.lang.annotation.Target;
27+
import java.util.List;
28+
import java.util.Map;
3129

32-
/**
33-
* Marks a method as an exception handler. The method is used by the annotation processor to handle
34-
* exceptions passing over the isolate boundary. The method returns {@code true} if it has handled
35-
* the given exception or {@code false} to perform the default exception handling.
36-
*/
37-
@Retention(RetentionPolicy.CLASS)
38-
@Target(ElementType.METHOD)
39-
public @interface ExceptionHandler {
30+
public interface CustomMarshallerService {
31+
32+
Map<String, String> createMap(List<String> keys, List<String> values);
33+
34+
Map<String, String> getProperties();
4035
}

compiler/src/org.graalvm.nativebridge.processor.test/src/org/graalvm/nativebridge/processor/test/common/InvalidExceptionHandler1Test.java

-58
This file was deleted.

compiler/src/org.graalvm.nativebridge.processor.test/src/org/graalvm/nativebridge/processor/test/common/InvalidExceptionHandler2Test.java

-52
This file was deleted.

compiler/src/org.graalvm.nativebridge.processor.test/src/org/graalvm/nativebridge/processor/test/common/InvalidExceptionHandler3Test.java

-52
This file was deleted.

compiler/src/org.graalvm.nativebridge.processor.test/src/org/graalvm/nativebridge/processor/test/common/InvalidExceptionHandler4Test.java

-52
This file was deleted.

0 commit comments

Comments
 (0)