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 };
|