< prev index next >

test/jdk/java/foreign/SafeFunctionAccessTest.java

Print this page
@@ -25,31 +25,35 @@
   * @test
   * @requires ((os.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64"
   * @run testng/othervm --enable-native-access=ALL-UNNAMED SafeFunctionAccessTest
   */
  
+ import jdk.incubator.foreign.Addressable;
  import jdk.incubator.foreign.CLinker;
  import jdk.incubator.foreign.FunctionDescriptor;
+ import jdk.incubator.foreign.NativeSymbol;
  import jdk.incubator.foreign.SymbolLookup;
- import jdk.incubator.foreign.MemoryAddress;
  import jdk.incubator.foreign.MemoryLayout;
  import jdk.incubator.foreign.MemorySegment;
  import jdk.incubator.foreign.ResourceScope;
  
  import java.lang.invoke.MethodHandle;
+ import java.lang.invoke.MethodHandles;
  import java.lang.invoke.MethodType;
  
+ import jdk.incubator.foreign.VaList;
  import org.testng.annotations.*;
+ 
  import static org.testng.Assert.*;
  
- public class SafeFunctionAccessTest {
+ public class SafeFunctionAccessTest extends NativeTestHelper {
      static {
          System.loadLibrary("SafeAccess");
      }
  
      static MemoryLayout POINT = MemoryLayout.structLayout(
-             CLinker.C_INT, CLinker.C_INT
+             C_INT, C_INT
      );
  
      static final SymbolLookup LOOKUP = SymbolLookup.loaderLookup();
  
      @Test(expectedExceptions = IllegalStateException.class)

@@ -57,28 +61,100 @@
          MemorySegment segment;
          try (ResourceScope scope = ResourceScope.newConfinedScope()) {
              segment = MemorySegment.allocateNative(POINT, scope);
          }
          assertFalse(segment.scope().isAlive());
-         MethodHandle handle = CLinker.getInstance().downcallHandle(
+         MethodHandle handle = CLinker.systemCLinker().downcallHandle(
                  LOOKUP.lookup("struct_func").get(),
-                 MethodType.methodType(void.class, MemorySegment.class),
                  FunctionDescriptor.ofVoid(POINT));
  
          handle.invokeExact(segment);
      }
  
      @Test(expectedExceptions = IllegalStateException.class)
-     public void testClosedPointer() throws Throwable {
-         MemoryAddress address;
+     public void testClosedVaList() throws Throwable {
+         VaList list;
+         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+             list = VaList.make(b -> b.addVarg(C_INT, 42), scope);
+         }
+         assertFalse(list.scope().isAlive());
+         MethodHandle handle = CLinker.systemCLinker().downcallHandle(
+                 LOOKUP.lookup("addr_func").get(),
+                 FunctionDescriptor.ofVoid(C_POINTER));
+ 
+         handle.invokeExact((Addressable)list);
+     }
+ 
+     @Test(expectedExceptions = IllegalStateException.class)
+     public void testClosedUpcall() throws Throwable {
+         NativeSymbol upcall;
          try (ResourceScope scope = ResourceScope.newConfinedScope()) {
-             address = MemorySegment.allocateNative(POINT, scope).address();
+             MethodHandle dummy = MethodHandles.lookup().findStatic(SafeFunctionAccessTest.class, "dummy", MethodType.methodType(void.class));
+             upcall = CLinker.systemCLinker().upcallStub(dummy, FunctionDescriptor.ofVoid(), scope);
          }
-         assertFalse(address.scope().isAlive());
-         MethodHandle handle = CLinker.getInstance().downcallHandle(
+         assertFalse(upcall.scope().isAlive());
+         MethodHandle handle = CLinker.systemCLinker().downcallHandle(
                  LOOKUP.lookup("addr_func").get(),
-                 MethodType.methodType(void.class, MemoryAddress.class),
-                 FunctionDescriptor.ofVoid(CLinker.C_POINTER));
+                 FunctionDescriptor.ofVoid(C_POINTER));
+ 
+         handle.invokeExact((Addressable)upcall);
+     }
+ 
+     static void dummy() { }
+ 
+     @Test
+     public void testClosedVaListCallback() throws Throwable {
+         MethodHandle handle = CLinker.systemCLinker().downcallHandle(
+                 LOOKUP.lookup("addr_func_cb").get(),
+                 FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));
+ 
+         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+             VaList list = VaList.make(b -> b.addVarg(C_INT, 42), scope);
+             handle.invoke(list, scopeChecker(scope));
+         }
+     }
+ 
+     @Test
+     public void testClosedStructCallback() throws Throwable {
+         MethodHandle handle = CLinker.systemCLinker().downcallHandle(
+                 LOOKUP.lookup("addr_func_cb").get(),
+                 FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));
+ 
+         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+             MemorySegment segment = MemorySegment.allocateNative(POINT, scope);
+             handle.invoke(segment, scopeChecker(scope));
+         }
+     }
  
-         handle.invokeExact(address);
+     @Test
+     public void testClosedUpcallCallback() throws Throwable {
+         MethodHandle handle = CLinker.systemCLinker().downcallHandle(
+                 LOOKUP.lookup("addr_func_cb").get(),
+                 FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));
+ 
+         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
+             MethodHandle dummy = MethodHandles.lookup().findStatic(SafeFunctionAccessTest.class, "dummy", MethodType.methodType(void.class));
+             NativeSymbol upcall = CLinker.systemCLinker().upcallStub(dummy, FunctionDescriptor.ofVoid(), scope);
+             handle.invoke(upcall, scopeChecker(scope));
+         }
+     }
+ 
+     NativeSymbol scopeChecker(ResourceScope scope) {
+         try {
+             MethodHandle handle = MethodHandles.lookup().findStatic(SafeFunctionAccessTest.class, "checkScope",
+                     MethodType.methodType(void.class, ResourceScope.class));
+             handle = handle.bindTo(scope);
+             return CLinker.systemCLinker().upcallStub(handle, FunctionDescriptor.ofVoid(), ResourceScope.newImplicitScope());
+         } catch (Throwable ex) {
+             throw new AssertionError(ex);
+         }
+     }
+ 
+     static void checkScope(ResourceScope scope) {
+         try {
+             scope.close();
+             fail("Scope closed unexpectedly!");
+         } catch (IllegalStateException ex) {
+             assertTrue(ex.getMessage().contains("kept alive")); //if acquired, fine
+         }
      }
  }
< prev index next >