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 package jdk.internal.nicl;
24
25 import jdk.internal.misc.Unsafe;
26 import jdk.internal.org.objectweb.asm.Type;
27
28 import java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodType;
30 import java.nicl.Library;
31 import java.nicl.metadata.LibraryDependencies;
32 import java.nicl.metadata.LibraryDependency;
33 import java.nicl.metadata.NativeType;
34 import java.util.Arrays;
35 import java.util.Map;
36 import java.util.WeakHashMap;
37 import java.security.AccessController;
38 import java.security.PrivilegedAction;
39
40 public class NativeLibraryImpl {
41 enum ImplType {
42 HEADER, CIVILIZED;
43
44 public String getImplName() {
45 return name().charAt(0) + name().substring(1).toLowerCase();
46 }
47 }
48
49 // Map of interface -> impl class (per ImplType)
50 @SuppressWarnings("unchecked")
51 private static final Map<Class<?>, Class<?>>[] IMPLEMENTATIONS = (Map<Class<?>, Class<?>>[]) new Map<?, ?>[ImplType.values().length];
52
53 static {
54 for (int i = 0; i < IMPLEMENTATIONS.length; i++) {
55 IMPLEMENTATIONS[i] = new WeakHashMap<>();
56 }
128 }
129
130 private static <T> Class<? extends T> getOrCreateCivilizedImpl(Class<T> c, T rawInstance)
131 throws SecurityException, InternalError {
132 /*
133 if (!c.isAnnotationPresent(Header.class)) {
134 throw new IllegalArgumentException("No @Header annotation on class " + c);
135 }
136 */
137
138 String implClassName = generateImplName(c, ImplType.CIVILIZED);
139
140 return getOrCreateImpl(ImplType.CIVILIZED, c, new CivilizedHeaderImplGenerator<>(c, implClassName, c, rawInstance));
141 }
142
143 private static Library loadLibrary(String name, boolean isAbsolute) {
144 return Platform.getInstance().loadLibrary(name, isAbsolute);
145 }
146
147 public static Library loadLibrary(String name) {
148 return loadLibrary(name, false);
149 }
150
151 public static Library loadLibraryFile(String name) {
152 return loadLibrary(name, true);
153 }
154
155 private static Library loadLibrary(LibraryDependency dep) {
156 if (dep.isAbsolute()) {
157 return loadLibraryFile(dep.name());
158 } else {
159 return loadLibrary(dep.name());
160 }
161 }
162
163 private static LibraryDependency[] getLibraryDependenciesForClass(Class<?> c) {
164 if (c.isAnnotationPresent(LibraryDependencies.class)) {
165 return c.getAnnotation(LibraryDependencies.class).value();
166 } else if (c.isAnnotationPresent(LibraryDependency.class)) {
167 return new LibraryDependency[] { c.getAnnotation(LibraryDependency.class) };
168 } else {
169 return null;
170 }
171 }
172
173 private static SymbolLookup getSymbolLookupForClass(Class<?> c) {
174 LibraryDependency[] deps = getLibraryDependenciesForClass(c);
175
176 Library[] libs;
177
178 if (deps == null) {
179 // FIXME: Require @LibraryDependency on all relevant classes
180 //System.err.println("WARNING: No @LibraryDependency annotation on class " + c.getName());
181 //throw new IllegalArgumentException("No @LibraryDependency annotation on class " + c.getName());
182 libs = new Library[] { getDefaultLibrary() };
183 } else {
184 libs = Arrays.stream(deps).map(NativeLibraryImpl::loadLibrary).toArray(Library[]::new);
185 }
186
187 return new SymbolLookup(libs);
188 }
189
190 public static Library getDefaultLibrary() {
191 return Platform.getInstance().defaultLibrary();
192 }
193
194 @Deprecated
195 public static <T> T bindRaw(Class<T> c, Library lib) {
196 return bindRaw(c, new SymbolLookup(new Library[] { lib }));
197 }
198
199 private static <T> T bindRaw(Class<T> c, SymbolLookup lookup) {
200 Class<? extends T> cls = getOrCreateImpl(c, lookup);
201
202 try {
203 //FIXME: Run some constructor here...?
204 @SuppressWarnings("unchecked")
|
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 package jdk.internal.nicl;
24
25 import jdk.internal.misc.Unsafe;
26 import jdk.internal.org.objectweb.asm.Type;
27
28 import java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodType;
30 import java.io.File;
31 import java.nicl.Library;
32 import java.nicl.NativeLibrary;
33 import java.nicl.metadata.LibraryDependencies;
34 import java.nicl.metadata.NativeType;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.util.Arrays;
39 import java.util.Map;
40 import java.util.WeakHashMap;
41 import java.util.Optional;
42 import java.security.AccessController;
43 import java.security.PrivilegedAction;
44
45 public class NativeLibraryImpl {
46 enum ImplType {
47 HEADER, CIVILIZED;
48
49 public String getImplName() {
50 return name().charAt(0) + name().substring(1).toLowerCase();
51 }
52 }
53
54 // Map of interface -> impl class (per ImplType)
55 @SuppressWarnings("unchecked")
56 private static final Map<Class<?>, Class<?>>[] IMPLEMENTATIONS = (Map<Class<?>, Class<?>>[]) new Map<?, ?>[ImplType.values().length];
57
58 static {
59 for (int i = 0; i < IMPLEMENTATIONS.length; i++) {
60 IMPLEMENTATIONS[i] = new WeakHashMap<>();
61 }
133 }
134
135 private static <T> Class<? extends T> getOrCreateCivilizedImpl(Class<T> c, T rawInstance)
136 throws SecurityException, InternalError {
137 /*
138 if (!c.isAnnotationPresent(Header.class)) {
139 throw new IllegalArgumentException("No @Header annotation on class " + c);
140 }
141 */
142
143 String implClassName = generateImplName(c, ImplType.CIVILIZED);
144
145 return getOrCreateImpl(ImplType.CIVILIZED, c, new CivilizedHeaderImplGenerator<>(c, implClassName, c, rawInstance));
146 }
147
148 private static Library loadLibrary(String name, boolean isAbsolute) {
149 return Platform.getInstance().loadLibrary(name, isAbsolute);
150 }
151
152 public static Library loadLibrary(String name) {
153 assert name.indexOf(File.separatorChar) == -1;
154 return loadLibrary(name, false);
155 }
156
157 public static Library load(String path) {
158 assert new File(path).isAbsolute();
159 return loadLibrary(path, true);
160 }
161
162 // return the absolute path of the library of given name by searching
163 // in the given array of paths.
164 private static Optional<Path> findLibraryPath(Path[] paths, String libName) {
165 return Arrays.stream(paths).
166 map(p -> p.resolve(System.mapLibraryName(libName))).
167 filter(Files::isRegularFile).map(Path::toAbsolutePath).findFirst();
168 }
169
170 private static Library[] loadLibraries(LibraryDependencies deps) {
171 String[] pathStrs = deps.paths();
172 if (pathStrs == null || pathStrs.length == 0) {
173 return Arrays.stream(deps.names()).map(
174 NativeLibrary::loadLibrary).toArray(Library[]::new);
175 } else {
176 Path[] paths = Arrays.stream(pathStrs).map(Paths::get).toArray(Path[]::new);
177 return Arrays.stream(deps.names()).map(libName -> {
178 Optional<Path> absPath = findLibraryPath(paths, libName);
179 return absPath.isPresent() ?
180 NativeLibrary.load(absPath.get().toString()) :
181 NativeLibrary.loadLibrary(libName);
182 }).toArray(Library[]::new);
183 }
184 }
185
186 private static LibraryDependencies getLibraryDependenciesForClass(Class<?> c) {
187 if (c.isAnnotationPresent(LibraryDependencies.class)) {
188 return c.getAnnotation(LibraryDependencies.class);
189 } else {
190 return null;
191 }
192 }
193
194 private static SymbolLookup getSymbolLookupForClass(Class<?> c) {
195 LibraryDependencies deps = getLibraryDependenciesForClass(c);
196
197 Library[] libs;
198
199 if (deps == null) {
200 // FIXME: Require @LibraryDependencies on all relevant classes
201 // System.err.println("WARNING: No @LibraryDependencies annotation on class " + c.getName());
202 // throw new IllegalArgumentException("No @LibraryDependencies annotation on class " + c.getName());
203 libs = new Library[] { getDefaultLibrary() };
204 } else {
205 libs = loadLibraries(deps);
206 }
207
208 return new SymbolLookup(libs);
209 }
210
211 public static Library getDefaultLibrary() {
212 return Platform.getInstance().defaultLibrary();
213 }
214
215 @Deprecated
216 public static <T> T bindRaw(Class<T> c, Library lib) {
217 return bindRaw(c, new SymbolLookup(new Library[] { lib }));
218 }
219
220 private static <T> T bindRaw(Class<T> c, SymbolLookup lookup) {
221 Class<? extends T> cls = getOrCreateImpl(c, lookup);
222
223 try {
224 //FIXME: Run some constructor here...?
225 @SuppressWarnings("unchecked")
|