aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java19
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java5
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java17
-rwxr-xr-xsrc/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java2
-rwxr-xr-xsrc/java/com/sun/gluegen/runtime/NativeLibrary.java61
-rwxr-xr-xsrc/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java2
6 files changed, 91 insertions, 15 deletions
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
index 423f009..8dc46ee 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
@@ -46,12 +46,14 @@ import com.sun.gluegen.cgram.types.*;
public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
private boolean callThroughProcAddress;
+ private boolean needsLocalTypedef;
private static String procAddressJavaTypeName =
JavaType.createForClass(Long.TYPE).jniTypeName();
private ProcAddressEmitter emitter;
public ProcAddressCMethodBindingEmitter(CMethodBindingEmitter methodToWrap,
final boolean callThroughProcAddress,
+ boolean needsLocalTypedef,
ProcAddressEmitter emitter) {
super(
new MethodBinding(methodToWrap.getBinding()) {
@@ -91,6 +93,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
setCommentEmitter(defaultCommentEmitter);
this.callThroughProcAddress = callThroughProcAddress;
+ this.needsLocalTypedef = needsLocalTypedef;
this.emitter = emitter;
}
@@ -112,10 +115,24 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
protected void emitBodyVariableDeclarations(PrintWriter writer) {
if (callThroughProcAddress) {
// create variable for the function pointer with the right type, and set
- // it to the value of the passed-in glProcAddress
+ // it to the value of the passed-in proc address
FunctionSymbol cSym = getBinding().getCSymbol();
String funcPointerTypedefName =
emitter.getFunctionPointerTypedefName(cSym);
+
+ if (needsLocalTypedef) {
+ // We (probably) didn't get a typedef for this function
+ // pointer type in the header file; the user requested that we
+ // forcibly generate one. Here we force the emission of one.
+ PointerType funcPtrType = new PointerType(null, cSym.getType(), 0);
+ // Just for safety, emit this name slightly differently than
+ // the mangling would otherwise produce
+ funcPointerTypedefName = "_local_" + funcPointerTypedefName;
+
+ writer.print(" typedef ");
+ writer.print(funcPtrType.toString(funcPointerTypedefName));
+ writer.println(";");
+ }
writer.print(" ");
writer.print(funcPointerTypedefName);
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java b/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java
index 54dd2cb..e5edd0d 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java
@@ -52,6 +52,7 @@ public class ProcAddressConfiguration extends JavaConfiguration
private String tableClassName = "ProcAddressTable";
private Set/*<String>*/ skipProcAddressGen = new HashSet();
private List/*<String>*/ forceProcAddressGen = new ArrayList();
+ private Set/*<String>*/ forceProcAddressGenSet = new HashSet();
private String getProcAddressTableExpr;
private ConvNode procAddressNameConverter;
@@ -78,6 +79,7 @@ public class ProcAddressConfiguration extends JavaConfiguration
{
String sym = readString("ForceProcAddressGen", tok, filename, lineNo);
forceProcAddressGen.add(sym);
+ forceProcAddressGenSet.add(sym);
}
else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr"))
{
@@ -253,4 +255,7 @@ public class ProcAddressConfiguration extends JavaConfiguration
return procAddressNameConverter.convert(funcName);
}
+ public boolean forceProcAddressGen(String funcName) {
+ return forceProcAddressGenSet.contains(funcName);
+ }
}
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
index 75fb59c..19d4fe3 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
@@ -58,6 +58,7 @@ public class ProcAddressEmitter extends JavaEmitter
protected static final String WRAP_PREFIX = "dispatch_";
private TypeDictionary typedefDictionary;
private PrintWriter tableWriter;
+ private Set emittedTableEntries;
private String tableClassPackage;
private String tableClassName;
@@ -219,6 +220,7 @@ public class ProcAddressEmitter extends JavaEmitter
{
// See whether we need a proc address entry for this one
boolean callThroughProcAddress = needsProcAddressWrapper(baseCEmitter.getBinding().getCSymbol());
+ boolean forceProcAddress = getProcAddressConfig().forceProcAddressGen(baseCEmitter.getBinding().getCSymbol().getName());
// Note that we don't care much about the naming of the C argument
// variables so to keep things simple we ignore the buffer object
// property for the binding
@@ -226,7 +228,10 @@ public class ProcAddressEmitter extends JavaEmitter
// The C-side JNI binding for this particular function will have an
// extra final argument, which is the address (the OpenGL procedure
// address) of the function it needs to call
- ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter(baseCEmitter, callThroughProcAddress, this);
+ ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter(baseCEmitter,
+ callThroughProcAddress,
+ forceProcAddress,
+ this);
MessageFormat exp = baseCEmitter.getReturnValueCapacityExpression();
if (exp != null) {
res.setReturnValueCapacityExpression(exp);
@@ -250,6 +255,10 @@ public class ProcAddressEmitter extends JavaEmitter
shouldWrap = false;
}
+ if (config.forceProcAddressGen(symName)) {
+ shouldWrap = true;
+ }
+
if (shouldWrap)
{
// Hoist argument names from function pointer if not supplied in prototype
@@ -281,6 +290,7 @@ public class ProcAddressEmitter extends JavaEmitter
CodeGenUtils.packageAsPath(implPackageName);
tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
+ emittedTableEntries = new HashSet();
CodeGenUtils.emitAutogeneratedWarning(tableWriter, this);
@@ -358,6 +368,11 @@ public class ProcAddressEmitter extends JavaEmitter
protected void emitProcAddressTableEntryForString(String str)
{
+ // Deal gracefully with forced proc address generation in the face
+ // of having the function pointer typedef in the header file too
+ if (emittedTableEntries.contains(str))
+ return;
+ emittedTableEntries.add(str);
tableWriter.print(" public long ");
tableWriter.print(PROCADDRESS_VAR_PREFIX);
tableWriter.print(str);
diff --git a/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java b/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java
index 37e3cd0..f998d07 100755
--- a/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java
+++ b/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java
@@ -34,7 +34,7 @@ public class MacOSXDynamicLinkerImpl implements DynamicLinker
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
- return dlopen(pathname, RTLD_GLOBAL);
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
public long lookupSymbol(long libraryHandle, String symbolName) {
diff --git a/src/java/com/sun/gluegen/runtime/NativeLibrary.java b/src/java/com/sun/gluegen/runtime/NativeLibrary.java
index f61afb6..01148b1 100755
--- a/src/java/com/sun/gluegen/runtime/NativeLibrary.java
+++ b/src/java/com/sun/gluegen/runtime/NativeLibrary.java
@@ -61,6 +61,7 @@ public class NativeLibrary {
private static final int WINDOWS = 1;
private static final int UNIX = 2;
private static final int MACOSX = 3;
+ private static boolean DEBUG;
private static int platform;
private static DynamicLinker dynLink;
private static String prefix;
@@ -78,6 +79,9 @@ public class NativeLibrary {
} else {
platform = UNIX;
}
+
+ DEBUG = (System.getProperty("gluegen.debug.NativeLibrary") != null);
+
return null;
}
});
@@ -118,35 +122,58 @@ public class NativeLibrary {
}
/** Opens the given native library, assuming it has the same base
- name on all platforms, in the context of the specified
- ClassLoader, which is used to help find the library in the case
- of e.g. Java Web Start. */
+ name on all platforms, looking first in the system's search
+ path, and in the context of the specified ClassLoader, which is
+ used to help find the library in the case of e.g. Java Web Start. */
public static NativeLibrary open(String libName, ClassLoader loader) {
- return open(libName, libName, libName, loader);
+ return open(libName, libName, libName, true, loader);
}
/** Opens the given native library, assuming it has the given base
names (no "lib" prefix or ".dll/.so/.dylib" suffix) on the
Windows, Unix and Mac OS X platforms, respectively, and in the
context of the specified ClassLoader, which is used to help find
- the library in the case of e.g. Java Web Start. */
+ the library in the case of e.g. Java Web Start. The
+ searchSystemPathFirst argument changes the behavior to first
+ search the default system path rather than searching it last.
+ Note that we do not currently handle DSO versioning on Unix.
+ Experience with JOAL and OpenAL has shown that it is extremely
+ problematic to rely on a specific .so version (for one thing,
+ ClassLoader.findLibrary on Unix doesn't work with files not
+ ending in .so, for example .so.0), and in general if this
+ dynamic loading facility is used correctly the version number
+ will be irrelevant.
+ */
public static NativeLibrary open(String windowsLibName,
String unixLibName,
String macOSXLibName,
+ boolean searchSystemPathFirst,
ClassLoader loader) {
List possiblePaths = enumerateLibraryPaths(windowsLibName,
unixLibName,
macOSXLibName,
+ searchSystemPathFirst,
loader);
// Iterate down these and see which one if any we can actually find.
for (Iterator iter = possiblePaths.iterator(); iter.hasNext(); ) {
String path = (String) iter.next();
+ if (DEBUG) {
+ System.out.println("Trying to load " + path);
+ }
ensureNativeLibLoaded();
long res = dynLink.openLibrary(path);
if (res != 0) {
+ if (DEBUG) {
+ System.out.println("Successfully loaded " + path + ": res = 0x" + Long.toHexString(res));
+ }
return new NativeLibrary(res, path);
}
}
+
+ if (DEBUG) {
+ System.out.println("Did not succeed in loading (" + windowsLibName + ", " + unixLibName + ", " + macOSXLibName + ")");
+ }
+
// For now, just return null to indicate the open operation didn't
// succeed (could also throw an exception if we could tell which
// of the openLibrary operations actually failed)
@@ -188,18 +215,28 @@ public class NativeLibrary {
private static List enumerateLibraryPaths(String windowsLibName,
String unixLibName,
String macOSXLibName,
+ boolean searchSystemPathFirst,
ClassLoader loader) {
+ List paths = new ArrayList();
String libName = selectName(windowsLibName, unixLibName, macOSXLibName);
+ if (libName == null)
+ return paths;
String[] baseNames = buildNames(libName);
- List paths = new ArrayList();
+ if (searchSystemPathFirst) {
+ // Add just the library names to use the OS's search algorithm
+ for (int i = 0; i < baseNames.length; i++) {
+ paths.add(baseNames[i]);
+ }
+ }
// The idea to ask the ClassLoader to find the library is borrowed
// from the LWJGL library
String clPath = getPathFromClassLoader(libName, loader);
- if (clPath != null)
+ if (clPath != null) {
paths.add(clPath);
-
+ }
+
// Add entries from java.library.path
String javaLibraryPath =
(String) AccessController.doPrivileged(new PrivilegedAction() {
@@ -223,9 +260,11 @@ public class NativeLibrary {
});
addPaths(userDir, baseNames, paths);
- // Add just the library names to use the OS's search algorithm
- for (int i = 0; i < baseNames.length; i++) {
- paths.add(baseNames[i]);
+ if (!searchSystemPathFirst) {
+ // Add just the library names to use the OS's search algorithm
+ for (int i = 0; i < baseNames.length; i++) {
+ paths.add(baseNames[i]);
+ }
}
return paths;
diff --git a/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java b/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java
index 006f90d..b6a79be 100755
--- a/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java
+++ b/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java
@@ -40,7 +40,7 @@ public class UnixDynamicLinkerImpl implements DynamicLinker
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
- return dlopen(pathname, RTLD_GLOBAL);
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
public long lookupSymbol(long libraryHandle, String symbolName) {