21 * questions. 22 */ 23 package jdk.internal.nicl; 24 25 import jdk.internal.misc.Unsafe; 26 import jdk.internal.nicl.types.BoundedMemoryRegion; 27 import jdk.internal.nicl.types.BoundedPointer; 28 import jdk.internal.nicl.types.DescriptorParser; 29 import jdk.internal.nicl.types.Types; 30 import jdk.internal.org.objectweb.asm.Type; 31 32 import java.lang.annotation.Native; 33 import java.lang.invoke.MethodType; 34 import java.lang.reflect.*; 35 import java.nicl.NativeTypes; 36 import java.nicl.Scope; 37 import java.nicl.layout.Address; 38 import java.nicl.layout.Function; 39 import java.nicl.layout.Layout; 40 import java.nicl.layout.Sequence; 41 import java.nicl.metadata.C; 42 import java.nicl.metadata.CallingConvention; 43 import java.nicl.metadata.NativeType; 44 import java.nicl.types.*; 45 import java.nicl.types.Array; 46 import java.nio.Buffer; 47 import java.nio.ByteBuffer; 48 import java.util.Objects; 49 50 public final class Util { 51 52 public static final long BYTE_BUFFER_BASE; 53 public static final long BUFFER_ADDRESS; 54 55 static { 56 try { 57 Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 58 unsafeField.setAccessible(true); 59 Unsafe UNSAFE = (Unsafe) unsafeField.get(null); 60 61 BYTE_BUFFER_BASE = UNSAFE.objectFieldOffset(ByteBuffer.class.getDeclaredField("hb")); 62 BUFFER_ADDRESS = UNSAFE.objectFieldOffset(Buffer.class.getDeclaredField("address")); 65 throw new InternalError(e); 66 } 67 } 68 69 private Util() { 70 } 71 72 public static Object getBufferBase(ByteBuffer bb) { 73 return UNSAFE.getObject(bb, BYTE_BUFFER_BASE); 74 } 75 76 public static long getBufferAddress(ByteBuffer bb) { 77 return UNSAFE.getLong(bb, BUFFER_ADDRESS); 78 } 79 80 public static long alignUp(long n, long alignment) { 81 return (n + alignment - 1) & ~(alignment - 1); 82 } 83 84 public static boolean isCStruct(Class<?> clz) { 85 if (!clz.isAnnotationPresent(C.class) || 86 !clz.isAnnotationPresent(NativeType.class)) { 87 return false; 88 } 89 NativeType nt = clz.getAnnotation(NativeType.class); 90 return nt.isRecordType(); 91 } 92 93 public static boolean isFunction(Class<?> clz) { 94 if (!isCStruct(clz)) { 95 return false; 96 } 97 98 return clz.isAnnotationPresent(CallingConvention.class); 99 } 100 101 public static Layout variadicLayout(Class<?> c) { 102 c = (Class<?>)unboxIfNeeded(c); 103 if (c.isPrimitive()) { 104 //it is ok to approximate with a machine word here; numerics arguments in a prototype-less 105 //function call are always rounded up to a register size anyway. 106 return Types.INT64; 107 } else if (Pointer.class.isAssignableFrom(c)) { 108 return Types.POINTER; 109 } else if (isFunctionalInterface(c)) { 110 return Types.POINTER; 111 } else if (isCStruct(c)) { 112 return layoutof(c); 113 } else { 114 throw new IllegalArgumentException("Unhandled variadic argument class: " + c); 115 } 116 } 117 118 public static Layout layoutof(Class<?> c) { 119 NativeType nt = c.getAnnotation(NativeType.class); 120 return new DescriptorParser(nt.layout()).parseLayout().findFirst().get(); 121 } 122 123 public static Function functionof(Method m) { 124 NativeType nt = m.getAnnotation(NativeType.class); 125 return (Function)new DescriptorParser(nt.layout()).parseDescriptorOrLayouts().findFirst().get(); 126 } 127 128 public static boolean isFunction(Method m) { 129 try { 130 functionof(m); 131 return true; 132 } catch (Throwable ex) { 133 return false; 134 } 135 } 136 137 static MethodType methodTypeFor(Method method) { 138 return MethodType.methodType(method.getReturnType(), method.getParameterTypes()); 139 } 140 141 public static boolean isFunctionalInterface(Class<?> c) { 142 return c.isAnnotationPresent(FunctionalInterface.class); 143 } | 21 * questions. 22 */ 23 package jdk.internal.nicl; 24 25 import jdk.internal.misc.Unsafe; 26 import jdk.internal.nicl.types.BoundedMemoryRegion; 27 import jdk.internal.nicl.types.BoundedPointer; 28 import jdk.internal.nicl.types.DescriptorParser; 29 import jdk.internal.nicl.types.Types; 30 import jdk.internal.org.objectweb.asm.Type; 31 32 import java.lang.annotation.Native; 33 import java.lang.invoke.MethodType; 34 import java.lang.reflect.*; 35 import java.nicl.NativeTypes; 36 import java.nicl.Scope; 37 import java.nicl.layout.Address; 38 import java.nicl.layout.Function; 39 import java.nicl.layout.Layout; 40 import java.nicl.layout.Sequence; 41 import java.nicl.metadata.NativeCallback; 42 import java.nicl.metadata.NativeLocation; 43 import java.nicl.metadata.NativeStruct; 44 import java.nicl.metadata.NativeType; 45 import java.nicl.types.*; 46 import java.nicl.types.Array; 47 import java.nio.Buffer; 48 import java.nio.ByteBuffer; 49 import java.util.Objects; 50 51 public final class Util { 52 53 public static final long BYTE_BUFFER_BASE; 54 public static final long BUFFER_ADDRESS; 55 56 static { 57 try { 58 Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); 59 unsafeField.setAccessible(true); 60 Unsafe UNSAFE = (Unsafe) unsafeField.get(null); 61 62 BYTE_BUFFER_BASE = UNSAFE.objectFieldOffset(ByteBuffer.class.getDeclaredField("hb")); 63 BUFFER_ADDRESS = UNSAFE.objectFieldOffset(Buffer.class.getDeclaredField("address")); 66 throw new InternalError(e); 67 } 68 } 69 70 private Util() { 71 } 72 73 public static Object getBufferBase(ByteBuffer bb) { 74 return UNSAFE.getObject(bb, BYTE_BUFFER_BASE); 75 } 76 77 public static long getBufferAddress(ByteBuffer bb) { 78 return UNSAFE.getLong(bb, BUFFER_ADDRESS); 79 } 80 81 public static long alignUp(long n, long alignment) { 82 return (n + alignment - 1) & ~(alignment - 1); 83 } 84 85 public static boolean isCStruct(Class<?> clz) { 86 return clz.isAnnotationPresent(NativeStruct.class); 87 } 88 89 public static Layout variadicLayout(Class<?> c) { 90 c = (Class<?>)unboxIfNeeded(c); 91 if (c.isPrimitive()) { 92 //it is ok to approximate with a machine word here; numerics arguments in a prototype-less 93 //function call are always rounded up to a register size anyway. 94 return Types.INT64; 95 } else if (Pointer.class.isAssignableFrom(c)) { 96 return Types.POINTER; 97 } else if (isFunctionalInterface(c)) { 98 return Types.POINTER; 99 } else if (isCStruct(c)) { 100 return layoutof(c); 101 } else { 102 throw new IllegalArgumentException("Unhandled variadic argument class: " + c); 103 } 104 } 105 106 public static Layout layoutof(Class<?> c) { 107 String layout; 108 if (c.isAnnotationPresent(NativeStruct.class)) { 109 layout = c.getAnnotation(NativeStruct.class).value(); 110 } else if (c.isAnnotationPresent(NativeType.class)) { 111 layout = c.getAnnotation(NativeType.class).layout(); 112 } else { 113 throw new IllegalArgumentException("@NativeStruct or @NativeType expected: " + c); 114 } 115 return new DescriptorParser(layout).parseLayout().findFirst().get(); 116 } 117 118 public static Function functionof(Class<?> c) { 119 if (! c.isAnnotationPresent(NativeCallback.class)) { 120 throw new IllegalArgumentException("@NativeCallback expected: " + c); 121 } 122 NativeCallback nc = c.getAnnotation(NativeCallback.class); 123 return (Function)new DescriptorParser(nc.value()).parseDescriptorOrLayouts().findFirst().get(); 124 } 125 126 public static Function functionof(Method m) { 127 if (! m.isAnnotationPresent(NativeType.class)) { 128 throw new IllegalArgumentException("@NativeType expected: " + m); 129 } 130 NativeType nt = m.getAnnotation(NativeType.class); 131 return (Function)new DescriptorParser(nt.layout()).parseDescriptorOrLayouts().findFirst().get(); 132 } 133 134 public static boolean isFunction(Method m) { 135 try { 136 functionof(m); 137 return true; 138 } catch (Throwable ex) { 139 return false; 140 } 141 } 142 143 static MethodType methodTypeFor(Method method) { 144 return MethodType.methodType(method.getReturnType(), method.getParameterTypes()); 145 } 146 147 public static boolean isFunctionalInterface(Class<?> c) { 148 return c.isAnnotationPresent(FunctionalInterface.class); 149 } |