# HG changeset patch # User Doug Simon # Date 1391786671 -3600 # Node ID fac51a64fda01f1680f1aeb047b5337ca9f26abe # Parent 8f3cd93813f10d011eea32c72ba22961d4dedc6a made NativeFunctionInterfaceTest pass on Windows diff -r 8f3cd93813f1 -r fac51a64fda0 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java --- 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); diff -r 8f3cd93813f1 -r fac51a64fda0 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java --- 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 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) { + } + } + } diff -r 8f3cd93813f1 -r fac51a64fda0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java --- 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);