< prev index next > test/jdk/java/foreign/capturecallstate/TestCaptureCallState.java
Print this page
* questions.
*/
/*
* @test
- * @enablePreview
* @library ../ /test/lib
- * @requires jdk.foreign.linker != "UNSUPPORTED"
* @run testng/othervm --enable-native-access=ALL-UNNAMED TestCaptureCallState
*/
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
System.load(system32 + "\\Kernel32.dll");
System.load(system32 + "\\Ws2_32.dll");
}
}
- private record SaveValuesCase(String nativeTarget, FunctionDescriptor nativeDesc, boolean trivial, String threadLocalName, Consumer<Object> resultCheck) {}
+ private record SaveValuesCase(String nativeTarget, FunctionDescriptor nativeDesc, String threadLocalName, Consumer<Object> resultCheck) {}
@Test(dataProvider = "cases")
public void testSavedThreadLocal(SaveValuesCase testCase) throws Throwable {
- List<Linker.Option> options = new ArrayList<>();
- options.add(Linker.Option.captureCallState(testCase.threadLocalName()));
- if (testCase.trivial()) {
- options.add(Linker.Option.isTrivial());
- }
- MethodHandle handle = downcallHandle(testCase.nativeTarget(), testCase.nativeDesc(), options.toArray(Linker.Option[]::new));
+ Linker.Option stl = Linker.Option.captureCallState(testCase.threadLocalName());
+ MethodHandle handle = downcallHandle(testCase.nativeTarget(), testCase.nativeDesc(), stl);
StructLayout capturedStateLayout = Linker.Option.captureStateLayout();
VarHandle errnoHandle = capturedStateLayout.varHandle(groupElement(testCase.threadLocalName()));
try (Arena arena = Arena.ofConfined()) {
boolean needsAllocator = testCase.nativeDesc().returnLayout().map(StructLayout.class::isInstance).orElse(false);
Object result = needsAllocator
? handle.invoke(arena, saveSeg, testValue)
: handle.invoke(saveSeg, testValue);
testCase.resultCheck().accept(result);
- int savedErrno = (int) errnoHandle.get(saveSeg);
+ int savedErrno = (int) errnoHandle.get(saveSeg, 0L);
assertEquals(savedErrno, testValue);
}
}
@Test(dataProvider = "invalidCaptureSegmentCases")
assertTrue(expectedExceptionType.isInstance(t));
assertTrue(t.getMessage().matches(expectedExceptionMessage));
}
}
- interface CaseAdder {
- void addCase(String nativeTarget, FunctionDescriptor nativeDesc, String threadLocalName, Consumer<Object> resultCheck);
- }
-
@DataProvider
public static Object[][] cases() {
List<SaveValuesCase> cases = new ArrayList<>();
- CaseAdder adder = (nativeTarget, nativeDesc, threadLocalName, resultCheck) -> {
- cases.add(new SaveValuesCase(nativeTarget, nativeDesc, false, threadLocalName, resultCheck));
- cases.add(new SaveValuesCase(nativeTarget, nativeDesc, true, threadLocalName, resultCheck));
- };
- adder.addCase("set_errno_V", FunctionDescriptor.ofVoid(JAVA_INT), "errno", o -> {});
- adder.addCase("set_errno_I", FunctionDescriptor.of(JAVA_INT, JAVA_INT), "errno", o -> assertEquals((int) o, 42));
- adder.addCase("set_errno_D", FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT), "errno", o -> assertEquals((double) o, 42.0));
-
- structCase(adder, "SL", Map.of(JAVA_LONG.withName("x"), 42L));
- structCase(adder, "SLL", Map.of(JAVA_LONG.withName("x"), 42L,
- JAVA_LONG.withName("y"), 42L));
- structCase(adder, "SLLL", Map.of(JAVA_LONG.withName("x"), 42L,
- JAVA_LONG.withName("y"), 42L,
- JAVA_LONG.withName("z"), 42L));
- structCase(adder, "SD", Map.of(JAVA_DOUBLE.withName("x"), 42D));
- structCase(adder, "SDD", Map.of(JAVA_DOUBLE.withName("x"), 42D,
- JAVA_DOUBLE.withName("y"), 42D));
- structCase(adder, "SDDD", Map.of(JAVA_DOUBLE.withName("x"), 42D,
- JAVA_DOUBLE.withName("y"), 42D,
- JAVA_DOUBLE.withName("z"), 42D));
+ cases.add(new SaveValuesCase("set_errno_V", FunctionDescriptor.ofVoid(JAVA_INT), "errno", o -> {}));
+ cases.add(new SaveValuesCase("set_errno_I", FunctionDescriptor.of(JAVA_INT, JAVA_INT), "errno", o -> assertEquals((int) o, 42)));
+ cases.add(new SaveValuesCase("set_errno_D", FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT), "errno", o -> assertEquals((double) o, 42.0)));
+
+ cases.add(structCase("SL", Map.of(JAVA_LONG.withName("x"), 42L)));
+ cases.add(structCase("SLL", Map.of(JAVA_LONG.withName("x"), 42L,
+ JAVA_LONG.withName("y"), 42L)));
+ cases.add(structCase("SLLL", Map.of(JAVA_LONG.withName("x"), 42L,
+ JAVA_LONG.withName("y"), 42L,
+ JAVA_LONG.withName("z"), 42L)));
+ cases.add(structCase("SD", Map.of(JAVA_DOUBLE.withName("x"), 42D)));
+ cases.add(structCase("SDD", Map.of(JAVA_DOUBLE.withName("x"), 42D,
+ JAVA_DOUBLE.withName("y"), 42D)));
+ cases.add(structCase("SDDD", Map.of(JAVA_DOUBLE.withName("x"), 42D,
+ JAVA_DOUBLE.withName("y"), 42D,
+ JAVA_DOUBLE.withName("z"), 42D)));
if (IS_WINDOWS) {
- adder.addCase("SetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "GetLastError", o -> {});
- adder.addCase("WSASetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "WSAGetLastError", o -> {});
+ cases.add(new SaveValuesCase("SetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "GetLastError", o -> {}));
+ cases.add(new SaveValuesCase("WSASetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "WSAGetLastError", o -> {}));
}
return cases.stream().map(tc -> new Object[] {tc}).toArray(Object[][]::new);
}
- static void structCase(CaseAdder adder, String name, Map<MemoryLayout, Object> fields) {
+ static SaveValuesCase structCase(String name, Map<MemoryLayout, Object> fields) {
StructLayout layout = MemoryLayout.structLayout(fields.keySet().toArray(MemoryLayout[]::new));
Consumer<Object> check = o -> {};
for (var field : fields.entrySet()) {
MemoryLayout fieldLayout = field.getKey();
VarHandle fieldHandle = layout.varHandle(MemoryLayout.PathElement.groupElement(fieldLayout.name().get()));
Object value = field.getValue();
- check = check.andThen(o -> assertEquals(fieldHandle.get(o), value));
+ check = check.andThen(o -> assertEquals(fieldHandle.get(o, 0L), value));
}
- adder.addCase("set_errno_" + name, FunctionDescriptor.of(layout, JAVA_INT), "errno", check);
+ return new SaveValuesCase("set_errno_" + name, FunctionDescriptor.of(layout, JAVA_INT), "errno", check);
}
@DataProvider
public static Object[][] invalidCaptureSegmentCases() {
return new Object[][]{
< prev index next >