< prev index next >

src/java.base/share/classes/jdk/internal/nicl/NativeLibraryImpl.java

Print this page




  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")


< prev index next >