< prev index next >

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

Print this page




  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.JavaLangAccess;
  26 import jdk.internal.misc.SharedSecrets;
  27 import jdk.internal.org.objectweb.asm.Type;
  28 
  29 import java.lang.invoke.MethodHandles.Lookup;
  30 import java.nicl.Library;
  31 import java.nicl.Libraries;
  32 import java.nicl.metadata.NativeHeader;

  33 import java.nicl.metadata.NativeType;
  34 import java.nio.file.Files;
  35 import java.nio.file.Path;
  36 import java.nio.file.Paths;
  37 import java.util.Arrays;
  38 import java.util.Map;
  39 import java.util.WeakHashMap;
  40 import java.util.Optional;
  41 import java.security.AccessController;
  42 import java.security.PrivilegedAction;
  43 
  44 public final class LibrariesHelper {
  45     private LibrariesHelper() {}
  46 
  47     private static final JavaLangAccess jlAccess = SharedSecrets.getJavaLangAccess();
  48 
  49     private static String generateImplName(Class<?> c) {
  50         return Type.getInternalName(c) + "$" + "Impl";
  51     }
  52 


  54      * Generate the implementation for an interface.
  55      *
  56      * @param c the interface for which to return an implementation class
  57      * @param generator a generator capable of generating an implementation, if needed
  58      * @return a class implementing the interface
  59      */
  60     private static Class<?> generateImpl(Class<?> c, BinderClassGenerator generator) {
  61         try {
  62             return AccessController.doPrivileged((PrivilegedAction<Class<?>>) () -> {
  63                     return generator.generate();
  64                 });
  65         } catch (Exception e) {
  66             throw new RuntimeException("Failed to generate implementation for class " + c, e);
  67         }
  68     }
  69 
  70     // Cache: Struct interface Class -> Impl Class.
  71     private static final ClassValue<Class<?>> STRUCT_IMPLEMENTATIONS = new ClassValue<>() {
  72         @Override
  73         protected Class<?> computeValue(Class<?> c) {
  74             assert c.isAnnotationPresent(NativeType.class) &&
  75                    c.getAnnotation(NativeType.class).isRecordType();
  76             return generateImpl(c, new StructImplGenerator(c, generateImplName(c), c));
  77         }
  78     };
  79 
  80     /**
  81      * Get the implementation for a Struct interface.
  82      *
  83      * @param c the Struct interface for which to return an implementation class
  84      * @return a class implementing the interface
  85      */
  86     @SuppressWarnings("unchecked")
  87     public static <T> Class<? extends T> getStructImplClass(Class<T> c) {
  88         boolean isRecordType = c.isAnnotationPresent(NativeType.class) &&
  89                     c.getAnnotation(NativeType.class).isRecordType();
  90         if (! isRecordType) {
  91             throw new IllegalArgumentException("Not a Struct interface: " + c);
  92         }
  93 
  94         return (Class<? extends T>)STRUCT_IMPLEMENTATIONS.get(c);
  95     }
  96 
  97     // This is used to pass the current SymbolLookup object to the header computeValue method below.
  98     private static final ThreadLocal<SymbolLookup> curSymLookup = new ThreadLocal<>();
  99 
 100     // Cache: Header interface Class -> Impl Class.
 101     private static final ClassValue<Class<?>> HEADER_IMPLEMENTATIONS = new ClassValue<>() {
 102         @Override
 103         protected Class<?> computeValue(Class<?> c) {
 104             assert c.isAnnotationPresent(NativeHeader.class);
 105             assert curSymLookup.get() != null;
 106             String implName = generateImplName(c);
 107             BinderClassGenerator generator = new HeaderImplGenerator(c, implName, c, curSymLookup.get());
 108             return generateImpl(c, generator);
 109         }
 110     };




  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.JavaLangAccess;
  26 import jdk.internal.misc.SharedSecrets;
  27 import jdk.internal.org.objectweb.asm.Type;
  28 
  29 import java.lang.invoke.MethodHandles.Lookup;
  30 import java.nicl.Library;
  31 import java.nicl.Libraries;
  32 import java.nicl.metadata.NativeHeader;
  33 import java.nicl.metadata.NativeStruct;
  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 final class LibrariesHelper {
  46     private LibrariesHelper() {}
  47 
  48     private static final JavaLangAccess jlAccess = SharedSecrets.getJavaLangAccess();
  49 
  50     private static String generateImplName(Class<?> c) {
  51         return Type.getInternalName(c) + "$" + "Impl";
  52     }
  53 


  55      * Generate the implementation for an interface.
  56      *
  57      * @param c the interface for which to return an implementation class
  58      * @param generator a generator capable of generating an implementation, if needed
  59      * @return a class implementing the interface
  60      */
  61     private static Class<?> generateImpl(Class<?> c, BinderClassGenerator generator) {
  62         try {
  63             return AccessController.doPrivileged((PrivilegedAction<Class<?>>) () -> {
  64                     return generator.generate();
  65                 });
  66         } catch (Exception e) {
  67             throw new RuntimeException("Failed to generate implementation for class " + c, e);
  68         }
  69     }
  70 
  71     // Cache: Struct interface Class -> Impl Class.
  72     private static final ClassValue<Class<?>> STRUCT_IMPLEMENTATIONS = new ClassValue<>() {
  73         @Override
  74         protected Class<?> computeValue(Class<?> c) {
  75             assert c.isAnnotationPresent(NativeStruct.class);

  76             return generateImpl(c, new StructImplGenerator(c, generateImplName(c), c));
  77         }
  78     };
  79 
  80     /**
  81      * Get the implementation for a Struct interface.
  82      *
  83      * @param c the Struct interface for which to return an implementation class
  84      * @return a class implementing the interface
  85      */
  86     @SuppressWarnings("unchecked")
  87     public static <T> Class<? extends T> getStructImplClass(Class<T> c) {
  88         if (!c.isAnnotationPresent(NativeStruct.class)) {


  89             throw new IllegalArgumentException("Not a Struct interface: " + c);
  90         }
  91 
  92         return (Class<? extends T>)STRUCT_IMPLEMENTATIONS.get(c);
  93     }
  94 
  95     // This is used to pass the current SymbolLookup object to the header computeValue method below.
  96     private static final ThreadLocal<SymbolLookup> curSymLookup = new ThreadLocal<>();
  97 
  98     // Cache: Header interface Class -> Impl Class.
  99     private static final ClassValue<Class<?>> HEADER_IMPLEMENTATIONS = new ClassValue<>() {
 100         @Override
 101         protected Class<?> computeValue(Class<?> c) {
 102             assert c.isAnnotationPresent(NativeHeader.class);
 103             assert curSymLookup.get() != null;
 104             String implName = generateImplName(c);
 105             BinderClassGenerator generator = new HeaderImplGenerator(c, implName, c, curSymLookup.get());
 106             return generateImpl(c, generator);
 107         }
 108     };


< prev index next >