changeset 13909:fac51a64fda0

made NativeFunctionInterfaceTest pass on Windows
author Doug Simon <doug.simon@oracle.com>
date Fri, 07 Feb 2014 16:24:31 +0100
parents 8f3cd93813f1
children d25c52a893d9
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java
diffstat 3 files changed, 113 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Fri Feb 07 15:20:59 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Fri Feb 07 16:24:31 2014 +0100
@@ -40,6 +40,13 @@
     NativeLibraryHandle getLibraryHandle(String libPath);
 
     /**
+     * Determines if the underlying platform/runtime supports the notion of a default library search
+     * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH}
+     * environment variable.
+     */
+    boolean isDefaultLibrarySearchSupported();
+
+    /**
      * Resolves the function pointer {@code NativeFunctionPointer} of a native function.
      * 
      * @param libraries the ordered list of libraries to search for the function
@@ -72,7 +79,7 @@
      * @param returnType the type of the return value
      * @param argumentTypes the types of the arguments
      * @return the function handle of the native function
-     * @throws UnsatisfiedLinkError if the function handle could not be created
+     * @throws UnsatisfiedLinkError the function handle could not be created
      */
     NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes);
 
@@ -99,7 +106,9 @@
      * @param returnType the type of the return value
      * @param argumentTypes the types of the arguments
      * @return the function handle of the native function
-     * @throws UnsatisfiedLinkError if the function could not be resolved
+     * @throws UnsatisfiedLinkError if default library searching is not
+     *             {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function
+     *             could not be resolved
      */
     NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java	Fri Feb 07 15:20:59 2014 +0100
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java	Fri Feb 07 16:24:31 2014 +0100
@@ -26,6 +26,7 @@
 import static java.io.File.*;
 import static java.lang.System.*;
 import static org.junit.Assert.*;
+import static org.junit.Assume.*;
 
 import java.io.*;
 import java.util.*;
@@ -39,13 +40,12 @@
 
 public class NativeFunctionInterfaceTest {
 
-    public final RuntimeProvider runtimeProvider;
-    public final NativeFunctionInterface ffi;
+    public final NativeFunctionInterface nfi;
 
     public NativeFunctionInterfaceTest() {
-        this.runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
+        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
         Assume.assumeTrue(runtimeProvider.getHostBackend() instanceof HostBackend);
-        ffi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface();
+        nfi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface();
     }
 
     private List<Long> allocations = new ArrayList<>();
@@ -72,10 +72,10 @@
 
     @Test
     public void test1() {
-
-        NativeFunctionHandle malloc = ffi.getFunctionHandle("malloc", long.class, int.class);
-        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class);
-        NativeFunctionHandle free = ffi.getFunctionHandle("free", void.class, long.class);
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        NativeFunctionHandle malloc = nfi.getFunctionHandle("malloc", long.class, int.class);
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class);
+        NativeFunctionHandle free = nfi.getFunctionHandle("free", void.class, long.class);
 
         String string = "GRAAL";
         int bufferLength = string.length() + 1;
@@ -93,6 +93,7 @@
 
     @Test
     public void test2() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         String formatString = "AB %f%f";
         long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
 
@@ -100,7 +101,7 @@
         int bufferLength = referenceString.length() + 1;
         long buffer = malloc(bufferLength);
 
-        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class);
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class);
         int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
 
         assertCStringEquals(buffer, referenceString);
@@ -109,6 +110,7 @@
 
     @Test
     public void test3() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         String format = "%i%i%i%i%i%i%i%i%i%i%i%i";
         long formatCString = writeCString(format, malloc(format.length() + 1));
         String referenceString = "01234567891011";
@@ -116,7 +118,7 @@
         int bufferLength = referenceString.length() + 1;
         long buffer = malloc(bufferLength);
 
-        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
                         int.class, int.class, int.class, int.class, int.class);
 
         int result = (int) snprintf.call(buffer, bufferLength, formatCString, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
@@ -126,6 +128,7 @@
 
     @Test
     public void test4() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         long str = malloc(49);
         int[] val = new int[12];
         for (int i = 0; i < 12; i++) {
@@ -146,7 +149,7 @@
 
         long buffer = malloc(bufferLength);
 
-        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
                         int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
                         double.class, double.class, double.class, double.class);
 
@@ -158,6 +161,7 @@
 
     @Test
     public void test5() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         long str = malloc(73);
         int[] val = new int[12];
         for (int i = 0; i < 12; i++) {
@@ -184,7 +188,7 @@
 
         long buffer = malloc(bufferLength);
 
-        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
                         int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
                         double.class, double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class,
                         char.class, char.class);
@@ -198,15 +202,17 @@
 
     @Test
     public void test6() {
-        NativeFunctionHandle handle = ffi.getFunctionHandle("pow", double.class, double.class, double.class);
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
         double result = (double) handle.call(3D, 5.5D);
         assertEquals(Math.pow(3D, 5.5D), result, 0);
     }
 
     @Test
     public void test7() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         double result = 0;
-        NativeFunctionHandle handle = ffi.getFunctionHandle("pow", double.class, double.class, double.class);
+        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
         for (int i = 0; i < 10; i++) {
             result = (double) handle.call(3D, 5.5D);
         }
@@ -215,6 +221,7 @@
 
     @Test
     public void test8() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         String formatString = "AB %f%f";
         long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
 
@@ -222,7 +229,7 @@
         int bufferLength = expected.length() + 1;
         byte[] buffer = new byte[bufferLength];
 
-        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class);
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class);
         int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
 
         // trim trailing '\0'
@@ -236,10 +243,11 @@
 
     @Test
     public void test9() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
         double[] src = someDoubles.clone();
         double[] dst = new double[src.length];
 
-        NativeFunctionHandle memcpy = ffi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class);
+        NativeFunctionHandle memcpy = nfi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class);
         memcpy.call(dst, src, src.length * (Double.SIZE / Byte.SIZE));
 
         assertArrayEquals(src, dst, 0.0D);
@@ -271,8 +279,8 @@
 
     @Test
     public void test10() {
-        NativeLibraryHandle vmLib = ffi.getLibraryHandle(getVMLibPath());
-        NativeFunctionHandle currentTimeMillis = ffi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class);
+        NativeLibraryHandle vmLib = nfi.getLibraryHandle(getVMLibPath());
+        NativeFunctionHandle currentTimeMillis = nfi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class);
         long time1 = (long) currentTimeMillis.call();
         long time2 = System.currentTimeMillis();
         long delta = time2 - time1;
@@ -299,32 +307,94 @@
 
     @Test
     public void test11() {
-        NativeLibraryHandle javaLib = ffi.getLibraryHandle(getJavaLibPath());
-        NativeFunctionHandle d2l = ffi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
         testD2L(d2l);
     }
 
     @Test
     public void test12() {
-        NativeLibraryHandle[] libs = {ffi.getLibraryHandle(getVMLibPath()), ffi.getLibraryHandle(getJavaLibPath())};
-        NativeFunctionHandle d2l = ffi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
         testD2L(d2l);
 
         NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
-        d2l = ffi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        d2l = nfi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
         testD2L(d2l);
     }
 
     @Test
     public void test13() {
-        NativeLibraryHandle[] libs = {ffi.getLibraryHandle(getVMLibPath()), ffi.getLibraryHandle(getJavaLibPath())};
-        NativeFunctionPointer functionPointer = ffi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits");
-        NativeFunctionHandle d2l = ffi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        NativeFunctionPointer functionPointer = nfi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits");
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
         testD2L(d2l);
 
         NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
-        functionPointer = ffi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits");
-        d2l = ffi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
+        functionPointer = nfi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits");
+        d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
         testD2L(d2l);
     }
+
+    @Test
+    public void test14() {
+        if (!nfi.isDefaultLibrarySearchSupported()) {
+            try {
+                nfi.getFunctionHandle("snprintf", int.class);
+                fail();
+            } catch (UnsatisfiedLinkError e) {
+            }
+        }
+    }
+
+    @Test
+    public void test15() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        try {
+            nfi.getFunctionHandle("an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test16() {
+        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
+        try {
+
+            nfi.getFunctionHandle(javaLib, "an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test17() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        try {
+            nfi.getFunctionPointer(libs, "an invalid function name");
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test18() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        try {
+            nfi.getFunctionHandle(libs, "an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test19() {
+        try {
+            nfi.getLibraryHandle("an invalid library name");
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Fri Feb 07 15:20:59 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Fri Feb 07 16:24:31 2014 +0100
@@ -181,6 +181,10 @@
         return lookupFunctionPointer(name, rtldDefault, true);
     }
 
+    public boolean isDefaultLibrarySearchSupported() {
+        return rtldDefault != null;
+    }
+
     @Override
     public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) {
         return new HotSpotNativeFunctionPointer(rawValue, null);