< prev index next >

test/jdk/java/foreign/capturecallstate/TestCaptureCallState.java

Print this page
*** 21,13 ***
   * 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;
--- 21,11 ---

*** 61,20 ***
              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) {}
  
      @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));
  
          StructLayout capturedStateLayout = Linker.Option.captureStateLayout();
          VarHandle errnoHandle = capturedStateLayout.varHandle(groupElement(testCase.threadLocalName()));
  
          try (Arena arena = Arena.ofConfined()) {
--- 59,16 ---
              System.load(system32 + "\\Kernel32.dll");
              System.load(system32 + "\\Ws2_32.dll");
          }
      }
  
!     private record SaveValuesCase(String nativeTarget, FunctionDescriptor nativeDesc, String threadLocalName, Consumer<Object> resultCheck) {}
  
      @Test(dataProvider = "cases")
      public void testSavedThreadLocal(SaveValuesCase testCase) throws Throwable {
!         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()) {

*** 83,11 ***
              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);
              assertEquals(savedErrno, testValue);
          }
      }
  
      @Test(dataProvider = "invalidCaptureSegmentCases")
--- 77,11 ---
              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, 0L);
              assertEquals(savedErrno, testValue);
          }
      }
  
      @Test(dataProvider = "invalidCaptureSegmentCases")

*** 103,59 ***
              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));
  
          if (IS_WINDOWS) {
!             adder.addCase("SetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "GetLastError", o -> {});
!             adder.addCase("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) {
          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));
          }
  
!         adder.addCase("set_errno_" + name, FunctionDescriptor.of(layout, JAVA_INT), "errno", check);
      }
  
      @DataProvider
      public static Object[][] invalidCaptureSegmentCases() {
          return new Object[][]{
--- 97,51 ---
              assertTrue(expectedExceptionType.isInstance(t));
              assertTrue(t.getMessage().matches(expectedExceptionMessage));
          }
      }
  
      @DataProvider
      public static Object[][] cases() {
          List<SaveValuesCase> cases = new ArrayList<>();
  
!         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) {
!             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 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, 0L), value));
          }
  
!         return new SaveValuesCase("set_errno_" + name, FunctionDescriptor.of(layout, JAVA_INT), "errno", check);
      }
  
      @DataProvider
      public static Object[][] invalidCaptureSegmentCases() {
          return new Object[][]{
< prev index next >