Skip to content
Permalink
Browse files
8275061: Exceptions thrown from non-void upcalls are not handled
Reviewed-by: mcimadamore
  • Loading branch information
JornVernee committed Oct 11, 2021
1 parent fd9d6cc commit 960846267ec1c3a907d363982ed5d0d0e1eaea1f
@@ -385,7 +385,11 @@ static MethodHandle wrapWithAllocator(MethodHandle specializedHandle,
insertPos = 1;
} else {
closer = identity(specializedHandle.type().returnType()); // (V) -> V
closer = dropArguments(closer, 0, Throwable.class); // (Throwable, V) -> V
if (!upcall) {
closer = dropArguments(closer, 0, Throwable.class); // (Throwable, V) -> V
} else {
closer = collectArguments(closer, 0, MH_HANDLE_UNCAUGHT_EXCEPTION); // (Throwable, V) -> V
}
insertPos = 2;
}

@@ -51,17 +51,17 @@ public class TestUpcallException {

@Test
public void testExceptionInterpreted() throws InterruptedException, IOException {
boolean useSpec = false;
run(useSpec);
run(/* useSpec = */ false, /* isVoid = */ true);
run(/* useSpec = */ false, /* isVoid = */ false);
}

@Test
public void testExceptionSpecialized() throws IOException, InterruptedException {
boolean useSpec = true;
run(useSpec);
run(/* useSpec = */ true, /* isVoid = */ true);
run(/* useSpec = */ true, /* isVoid = */ false);
}

private void run(boolean useSpec) throws IOException, InterruptedException {
private void run(boolean useSpec, boolean isVoid) throws IOException, InterruptedException {
Process process = new ProcessBuilder()
.command(
Paths.get(Utils.TEST_JDK)
@@ -74,7 +74,8 @@ private void run(boolean useSpec) throws IOException, InterruptedException {
"-Djava.library.path=" + System.getProperty("java.library.path"),
"-Djdk.internal.foreign.ProgrammableUpcallHandler.USE_SPEC=" + useSpec,
"-cp", Utils.TEST_CLASS_PATH,
"ThrowingUpcall")
"ThrowingUpcall",
isVoid ? "void" : "non-void")
.start();

int result = process.waitFor();
@@ -21,10 +21,8 @@
* questions.
*/

import jdk.incubator.foreign.Addressable;
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.NativeSymbol;
import jdk.incubator.foreign.ResourceScope;
import jdk.incubator.foreign.SymbolLookup;
@@ -35,16 +33,21 @@

public class ThrowingUpcall extends NativeTestHelper {

private static final MethodHandle downcall;
private static final MethodHandle downcallVoid;
private static final MethodHandle downcallNonVoid;
public static final MethodHandle MH_throwException;

static {
System.loadLibrary("TestUpcall");
SymbolLookup lookup = SymbolLookup.loaderLookup();
downcall = CLinker.systemCLinker().downcallHandle(
downcallVoid = CLinker.systemCLinker().downcallHandle(
lookup.lookup("f0_V__").orElseThrow(),
FunctionDescriptor.ofVoid(C_POINTER)
);
downcallNonVoid = CLinker.systemCLinker().downcallHandle(
lookup.lookup("f10_I_I_").orElseThrow(),
FunctionDescriptor.of(C_INT, C_INT, C_POINTER)
);

try {
MH_throwException = MethodHandles.lookup().findStatic(ThrowingUpcall.class, "throwException",
@@ -59,18 +62,35 @@ public static void throwException() throws Throwable {
}

public static void main(String[] args) throws Throwable {
test();
if (args[0].equals("void")) {
testVoid();
} else {
testNonVoid();
}
}

public static void test() throws Throwable {
public static void testVoid() throws Throwable {
MethodHandle handle = MH_throwException;
MethodHandle invoker = MethodHandles.exactInvoker(MethodType.methodType(void.class));
handle = MethodHandles.insertArguments(invoker, 0, handle);

try (ResourceScope scope = ResourceScope.newConfinedScope()) {
NativeSymbol stub = CLinker.systemCLinker().upcallStub(handle, FunctionDescriptor.ofVoid(), scope);

downcall.invoke(stub); // should call Shutdown.exit(1);
downcallVoid.invoke(stub); // should call Shutdown.exit(1);
}
}

public static void testNonVoid() throws Throwable {
MethodHandle handle = MethodHandles.identity(int.class);
handle = MethodHandles.collectArguments(handle, 0, MH_throwException);
MethodHandle invoker = MethodHandles.exactInvoker(MethodType.methodType(int.class, int.class));
handle = MethodHandles.insertArguments(invoker, 0, handle);

try (ResourceScope scope = ResourceScope.newConfinedScope()) {
NativeSymbol stub = CLinker.systemCLinker().upcallStub(handle, FunctionDescriptor.of(C_INT, C_INT), scope);

downcallNonVoid.invoke(42, stub); // should call Shutdown.exit(1);
}
}

0 comments on commit 9608462

Please sign in to comment.