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.  Oracle designates this
 8  *  particular file as subject to the "Classpath" exception as provided
 9  *  by Oracle in the LICENSE file that accompanied this code.
10  *
11  *  This code is distributed in the hope that it will be useful, but WITHOUT
12  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  *  version 2 for more details (a copy is included in the LICENSE file that
15  *  accompanied this code).
16  *
17  *  You should have received a copy of the GNU General Public License version
18  *  2 along with this work; if not, write to the Free Software Foundation,
19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  *  or visit www.oracle.com if you need additional information or have any
23  *  questions.
24  *
25  */
26 package jdk.incubator.foreign;
27 
28 import jdk.internal.foreign.NativeSymbolImpl;
29 import jdk.internal.reflect.CallerSensitive;
30 import jdk.internal.reflect.Reflection;
31 
32 import java.lang.invoke.MethodHandle;
33 import java.util.Objects;
34 
35 /**
36  * A native symbol models a reference to a location (typically the entry point of a function) in a native library.
37  * A native symbol has a name, and is associated with a scope, which governs the native symbol's lifecycle.
38  * This is useful, since the library a native symbol refers to can be <em>unloaded</em>, thus invalidating the native symbol.
39  * While native symbols are typically obtained using a {@link SymbolLookup#lookup(String) symbol lookup}, it is also possible to obtain an
40  * <em>anonymous</em> native symbol, in the form of an {@linkplain CLinker#upcallStub(MethodHandle, FunctionDescriptor, ResourceScope) upcall stub},
41  * that is, a reference to a dynamically-generated native symbol which can be used to call back into Java code.
42  */
43 sealed public interface NativeSymbol extends Addressable permits NativeSymbolImpl {
44 
45     /**
46      * Returns the name of this symbol.
47      * @return the name of this symbol.
48      */
49     String name();
50 
51     /**
52      * Returns the resource scope associated with this symbol.
53      * @return the resource scope associated with this symbol.
54      */
55     ResourceScope scope();
56 
57     /**
58      * Returns the memory address associated with this symbol.
59      * @throws IllegalStateException if the scope associated with this symbol has been closed, or if access occurs from
60      * a thread other than the thread owning that scope.
61      * @return The memory address associated with this symbol.
62      */
63     @Override
64     MemoryAddress address();
65 
66     /**
67      * Creates a new symbol from given name, address and scope.
68      * <p>
69      * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
70      * Restricted methods are unsafe, and, if used incorrectly, their use might crash
71      * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
72      * restricted methods, and use safe and supported functionalities, where possible.
73      * @param name the symbol name.
74      * @param address the symbol address.
75      * @param scope the symbol scope.
76      * @return A new symbol from given name, address and scope.
77      * @throws IllegalCallerException if access to this method occurs from a module {@code M} and the command line option
78      * {@code --enable-native-access} is either absent, or does not mention the module name {@code M}, or
79      * {@code ALL-UNNAMED} in case {@code M} is an unnamed module.
80      */
81     @CallerSensitive
82     static NativeSymbol ofAddress(String name, MemoryAddress address, ResourceScope scope) {
83         Reflection.ensureNativeAccess(Reflection.getCallerClass());
84         Objects.requireNonNull(name);
85         Objects.requireNonNull(address);
86         Objects.requireNonNull(scope);
87         return new NativeSymbolImpl(name, address, scope);
88     }
89 }