1 /*
 2  *  Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
 3  *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  *
 5  *  This code is free software; you can redistribute it and/or modify it
 6  *  under the terms of the GNU General Public License version 2 only, as
 7  *  published by the Free Software Foundation.
 8  *
 9  *  This code is distributed in the hope that it will be useful, but WITHOUT
10  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  *  version 2 for more details (a copy is included in the LICENSE file that
13  *  accompanied this code).
14  *
15  *  You should have received a copy of the GNU General Public License version
16  *  2 along with this work; if not, write to the Free Software Foundation,
17  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  *  or visit www.oracle.com if you need additional information or have any
21  *  questions.
22  */
23 
24 /*
25  * @test
26  * @requires ((os.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64"
27  * @run testng/othervm --enable-native-access=ALL-UNNAMED SafeFunctionAccessTest
28  */
29 
30 import jdk.incubator.foreign.CLinker;
31 import jdk.incubator.foreign.FunctionDescriptor;
32 import jdk.incubator.foreign.SymbolLookup;
33 import jdk.incubator.foreign.MemoryAddress;
34 import jdk.incubator.foreign.MemoryLayout;
35 import jdk.incubator.foreign.MemorySegment;
36 import jdk.incubator.foreign.ResourceScope;
37 
38 import java.lang.invoke.MethodHandle;
39 import java.lang.invoke.MethodType;
40 
41 import org.testng.annotations.*;
42 import static org.testng.Assert.*;
43 
44 public class SafeFunctionAccessTest {
45     static {
46         System.loadLibrary("SafeAccess");
47     }
48 
49     static MemoryLayout POINT = MemoryLayout.structLayout(
50             CLinker.C_INT, CLinker.C_INT
51     );
52 
53     static final SymbolLookup LOOKUP = SymbolLookup.loaderLookup();
54 
55     @Test(expectedExceptions = IllegalStateException.class)
56     public void testClosedStruct() throws Throwable {
57         MemorySegment segment;
58         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
59             segment = MemorySegment.allocateNative(POINT, scope);
60         }
61         assertFalse(segment.scope().isAlive());
62         MethodHandle handle = CLinker.getInstance().downcallHandle(
63                 LOOKUP.lookup("struct_func").get(),
64                 MethodType.methodType(void.class, MemorySegment.class),
65                 FunctionDescriptor.ofVoid(POINT));
66 
67         handle.invokeExact(segment);
68     }
69 
70     @Test(expectedExceptions = IllegalStateException.class)
71     public void testClosedPointer() throws Throwable {
72         MemoryAddress address;
73         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
74             address = MemorySegment.allocateNative(POINT, scope).address();
75         }
76         assertFalse(address.scope().isAlive());
77         MethodHandle handle = CLinker.getInstance().downcallHandle(
78                 LOOKUP.lookup("addr_func").get(),
79                 MethodType.methodType(void.class, MemoryAddress.class),
80                 FunctionDescriptor.ofVoid(CLinker.C_POINTER));
81 
82         handle.invokeExact(address);
83     }
84 }