summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nbproject/ide-file-targets.xml1
-rwxr-xr-xsrc/java/com/jogamp/common/os/DynamicLibraryBundle.java14
-rw-r--r--src/java/com/jogamp/common/os/Platform.java76
-rw-r--r--src/java/com/jogamp/common/util/MiscUtils.java57
-rw-r--r--src/java/com/jogamp/common/util/ReflectionUtil.java36
-rw-r--r--src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java177
-rw-r--r--src/java/com/sun/gluegen/JavaEmitter.java4
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java76
-rw-r--r--test/junit/com/sun/gluegen/BasicProcAddressEmitterTest.java68
-rw-r--r--test/junit/com/sun/gluegen/BuildUtil.java14
-rw-r--r--test/junit/com/sun/gluegen/dyntest.cfg25
11 files changed, 337 insertions, 211 deletions
diff --git a/nbproject/ide-file-targets.xml b/nbproject/ide-file-targets.xml
index 343f527..d879376 100644
--- a/nbproject/ide-file-targets.xml
+++ b/nbproject/ide-file-targets.xml
@@ -50,7 +50,6 @@
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
<formatter type="brief" usefile="false"/>
</junit>
- <java classname="${run.class}" fork="true"/>
</target>
<!-- TODO: edit the following target according to your needs -->
<!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#runsingle) -->
diff --git a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java
index 8e138ef..6c00afe 100755
--- a/src/java/com/jogamp/common/os/DynamicLibraryBundle.java
+++ b/src/java/com/jogamp/common/os/DynamicLibraryBundle.java
@@ -28,10 +28,8 @@
package com.jogamp.common.os;
import java.util.*;
-import java.security.*;
import com.jogamp.common.jvm.JNILibLoaderBase;
-import com.jogamp.common.util.MiscUtils;
/**
* Provides bundling of:<br>
@@ -87,10 +85,10 @@ public class DynamicLibraryBundle implements DynamicLookupHelper {
}
if(DEBUG) {
System.out.println("DynamicLibraryBundle.init Summary: "+info.getClass().getName());
- System.out.println(" toolGetProcAddressFuncNameList: "+MiscUtils.toString(toolGetProcAddressFuncNameList));
- System.out.println(" Tool Lib Names : "+MiscUtils.toString(toolLibNames));
+ System.out.println(" toolGetProcAddressFuncNameList: "+toolGetProcAddressFuncNameList);
+ System.out.println(" Tool Lib Names : "+toolLibNames);
System.out.println(" Tool Lib Loaded: "+getToolLibLoadedNumber()+"/"+getToolLibNumber()+", complete "+isToolLibComplete());
- System.out.println(" Glue Lib Names : "+MiscUtils.toString(glueLibNames));
+ System.out.println(" Glue Lib Names : "+glueLibNames);
System.out.println(" Glue Lib Loaded: "+getGlueLibLoadedNumber()+"/"+getGlueLibNumber()+", complete "+isGlueLibComplete());
System.out.println(" All Complete: "+isLibComplete());
}
@@ -209,13 +207,13 @@ public class DynamicLibraryBundle implements DynamicLookupHelper {
libNames = new ArrayList();
libNames.add((String)listObj);
} else {
- throw new RuntimeException("List element "+i+" must be either a List or String: "+MiscUtils.toString(toolLibNames));
+ throw new RuntimeException("List element "+i+" must be either a List or String: "+toolLibNames);
}
if( null != libNames && libNames.size() > 0 ) {
lib = loadFirstAvailable(libNames, loader, info.shallLinkGlobal());
if ( null == lib ) {
if(DEBUG) {
- System.out.println("Unable to load any Tool library of: "+MiscUtils.toString(libNames));
+ System.out.println("Unable to load any Tool library of: "+libNames);
}
} else {
nativeLibraries.add(lib);
@@ -283,7 +281,7 @@ public class DynamicLibraryBundle implements DynamicLookupHelper {
if(0!=addr) {
System.err.println("Lookup-Native: <" + funcName + "> 0x" + Long.toHexString(addr) + " in lib " + libName );
} else {
- System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** in libs " + MiscUtils.toString(nativeLibraries));
+ System.err.println("Lookup-Native: <" + funcName + "> ** FAILED ** in libs " + nativeLibraries);
}
}
return addr;
diff --git a/src/java/com/jogamp/common/os/Platform.java b/src/java/com/jogamp/common/os/Platform.java
index b6298a7..0d8b276 100644
--- a/src/java/com/jogamp/common/os/Platform.java
+++ b/src/java/com/jogamp/common/os/Platform.java
@@ -34,20 +34,21 @@ import com.jogamp.common.nio.Buffers;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
-import java.security.*;
/**
* Utility class for querying platform specific properties.
- * @author Michael Bien, Sven Gothel
+ * @author Michael Bien
+ * @author Sven Gothel
*/
public class Platform {
public static final boolean JAVA_SE;
public static final boolean LITTLE_ENDIAN;
+ public static final String OS;
+ public static final String ARCH;
- private final static boolean is32Bit;
- private final static int pointerSizeInBits;
- private final static String os, arch;
+ private static final boolean is32Bit;
+ private static final int pointerSizeInBits;
static {
NativeLibrary.ensureNativeLibLoaded();
@@ -55,17 +56,24 @@ public class Platform {
// We don't seem to need an AccessController.doPrivileged() block
// here as these system properties are visible even to unsigned
// applets
- os = System.getProperty("os.name");
- arch = System.getProperty("os.arch");
+ OS = System.getProperty("os.name");
+ ARCH = System.getProperty("os.arch");
pointerSizeInBits = getPointerSizeInBitsImpl();
+ is32Bit = initAch();
+ JAVA_SE = initIsJavaSE();
+ LITTLE_ENDIAN = initByteOrder();
+ }
+
+ private Platform() {}
- // Try to use Sun's sun.arch.data.model first ..
+ private static boolean initAch() throws RuntimeException {
+ // Try to use Sun's sun.ARCH.data.model first ..
if ( 32 == pointerSizeInBits || 64 == pointerSizeInBits ) {
- is32Bit = ( 32 == pointerSizeInBits );
+ return 32 == pointerSizeInBits;
}else {
- String os_lc = os.toLowerCase();
- String arch_lc = arch.toLowerCase();
+ String os_lc = OS.toLowerCase();
+ String arch_lc = ARCH.toLowerCase();
if ((os_lc.startsWith("windows") && arch_lc.equals("x86")) ||
(os_lc.startsWith("windows") && arch_lc.equals("arm")) ||
@@ -79,7 +87,7 @@ public class Platform {
(os_lc.startsWith("sunos_lc") && arch_lc.equals("x86")) ||
(os_lc.startsWith("freebsd") && arch_lc.equals("i386")) ||
(os_lc.startsWith("hp-ux") && arch_lc.equals("pa_risc2.0"))) {
- is32Bit = true;
+ return true;
} else if ((os_lc.startsWith("windows") && arch_lc.equals("amd64")) ||
(os_lc.startsWith("linux") && arch_lc.equals("amd64")) ||
(os_lc.startsWith("linux") && arch_lc.equals("x86_64")) ||
@@ -88,44 +96,41 @@ public class Platform {
(os_lc.startsWith("darwin") && arch_lc.equals("x86_64")) ||
(os_lc.startsWith("sunos_lc") && arch_lc.equals("sparcv9")) ||
(os_lc.startsWith("sunos_lc") && arch_lc.equals("amd64"))) {
- is32Bit = false;
+ return false;
}else{
throw new RuntimeException("Please port CPU detection (32/64 bit) to your platform (" + os_lc + "/" + arch_lc + ")");
}
}
+ }
+
+ private static boolean initIsJavaSE() {
+
+ // fast path for desktop
+ if(System.getSecurityManager() == null && System.getProperty("java.runtime.name").indexOf("Java SE") != -1) {
+ return true;
+ }
- boolean se;
+ // probe for classes we need on a SE environment
try{
Class.forName("java.nio.LongBuffer");
Class.forName("java.nio.DoubleBuffer");
- se = true;
+ return true;
}catch(ClassNotFoundException ex) {
- se = false;
+ return false;
}
+ }
- if(!se) {
- // no more the fast path, due to access controller ..
- String java_runtime_name = (String) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- return System.getProperty("java.runtime.name");
- }
- });
- se = java_runtime_name.indexOf("Java SE") != -1;
- }
- JAVA_SE = se;
-
- // byte order
+ private static boolean initByteOrder() {
ByteBuffer tst_b = Buffers.newDirectByteBuffer(Buffers.SIZEOF_INT); // 32bit in native order
IntBuffer tst_i = tst_b.asIntBuffer();
ShortBuffer tst_s = tst_b.asShortBuffer();
tst_i.put(0, 0x0A0B0C0D);
- LITTLE_ENDIAN = 0x0C0D == tst_s.get(0);
+ return 0x0C0D == tst_s.get(0);
}
- private Platform() {}
-
private static native int getPointerSizeInBitsImpl();
+
/**
* Returns true only if this program is running on the Java Standard Edition.
*/
@@ -144,14 +149,14 @@ public class Platform {
* Returns the OS name.
*/
public static String getOS() {
- return os;
+ return OS;
}
/**
* Returns the CPU architecture String.
*/
public static String getArch() {
- return arch;
+ return ARCH;
}
/**
@@ -165,6 +170,9 @@ public class Platform {
return pointerSizeInBits;
}
-}
+ public static int getPointerSizeInBytes() {
+ return pointerSizeInBits/8;
+ }
+}
diff --git a/src/java/com/jogamp/common/util/MiscUtils.java b/src/java/com/jogamp/common/util/MiscUtils.java
deleted file mode 100644
index dd32951..0000000
--- a/src/java/com/jogamp/common/util/MiscUtils.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2010, Sven Gothel
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of Sven Gothel nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Sven Gothel BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jogamp.common.util;
-
-import java.util.*;
-
-public class MiscUtils {
-
- public static StringBuffer append(StringBuffer sb, List list) {
- sb.append("[");
- if(null!=list&&list.size()>0) {
- boolean comma = false;
- for(Iterator iter=list.iterator(); iter.hasNext(); ) {
- if(comma) { sb.append(", "); }
- Object o = iter.next();
- if(o instanceof List) {
- sb = append(sb, (List)o);
- } else {
- sb.append(o);
- }
- comma = true;
- }
- }
- sb.append("]");
- return sb;
- }
-
- public static String toString(List list) {
- return append(new StringBuffer(), list).toString();
- }
-}
-
diff --git a/src/java/com/jogamp/common/util/ReflectionUtil.java b/src/java/com/jogamp/common/util/ReflectionUtil.java
index b9c6ef0..fc4352f 100644
--- a/src/java/com/jogamp/common/util/ReflectionUtil.java
+++ b/src/java/com/jogamp/common/util/ReflectionUtil.java
@@ -47,9 +47,9 @@ public final class ReflectionUtil {
/**
* Returns true only if the class could be loaded.
*/
- public static final boolean isClassAvailable(String clazzName) {
+ public static final boolean isClassAvailable(String clazzName, ClassLoader cl) {
try {
- return null != Class.forName(clazzName, false, ReflectionUtil.class.getClassLoader());
+ return null != Class.forName(clazzName, false, cl);
} catch (ClassNotFoundException e) {
return false;
}
@@ -59,26 +59,26 @@ public final class ReflectionUtil {
* Loads and returns the class or null.
* @see Class#forName(java.lang.String, boolean, java.lang.ClassLoader)
*/
- public static final Class getClass(String clazzName, boolean initialize)
+ public static final Class getClass(String clazzName, boolean initialize, ClassLoader cl)
throws JogampRuntimeException {
try {
- return getClassImpl(clazzName, initialize);
+ return getClassImpl(clazzName, initialize, cl);
} catch (ClassNotFoundException e) {
throw new JogampRuntimeException(clazzName + " not available", e);
}
}
- private static Class getClassImpl(String clazzName, boolean initialize) throws ClassNotFoundException {
- return Class.forName(clazzName, initialize, ReflectionUtil.class.getClassLoader());
+ private static Class getClassImpl(String clazzName, boolean initialize, ClassLoader cl) throws ClassNotFoundException {
+ return Class.forName(clazzName, initialize, cl);
}
/**
* @throws JogampRuntimeException if the constructor can not be delivered.
*/
- public static final Constructor getConstructor(String clazzName, Class[] cstrArgTypes)
+ public static final Constructor getConstructor(String clazzName, ClassLoader cl, Class[] cstrArgTypes)
throws JogampRuntimeException {
try {
- return getConstructor(getClassImpl(clazzName, true), cstrArgTypes);
+ return getConstructor(getClassImpl(clazzName, true, cl), cstrArgTypes);
} catch (ClassNotFoundException ex) {
throw new JogampRuntimeException(clazzName + " not available", ex);
}
@@ -109,9 +109,9 @@ public final class ReflectionUtil {
}
}
- public static final Constructor getConstructor(String clazzName)
+ public static final Constructor getConstructor(String clazzName, ClassLoader cl)
throws JogampRuntimeException {
- return getConstructor(clazzName, new Class[0]);
+ return getConstructor(clazzName, cl, new Class[0]);
}
/**
@@ -147,30 +147,30 @@ public final class ReflectionUtil {
return createInstance(clazz, cstrArgTypes, cstrArgs);
}
- public static final Object createInstance(String clazzName, Class[] cstrArgTypes, Object[] cstrArgs)
+ public static final Object createInstance(String clazzName, ClassLoader cl, Class[] cstrArgTypes, Object[] cstrArgs)
throws JogampRuntimeException, RuntimeException
{
try {
- return createInstance(getClassImpl(clazzName, true), cstrArgTypes, cstrArgs);
+ return createInstance(getClassImpl(clazzName, true, cl), cstrArgTypes, cstrArgs);
} catch (ClassNotFoundException ex) {
throw new JogampRuntimeException(clazzName + " not available", ex);
}
}
- public static final Object createInstance(String clazzName, Object[] cstrArgs)
+ public static final Object createInstance(String clazzName, ClassLoader cl, Object[] cstrArgs)
throws JogampRuntimeException, RuntimeException
{
Class[] cstrArgTypes = new Class[cstrArgs.length];
for(int i=0; i<cstrArgs.length; i++) {
cstrArgTypes[i] = cstrArgs[i].getClass();
}
- return createInstance(clazzName, cstrArgTypes, cstrArgs);
+ return createInstance(clazzName, cl, cstrArgTypes, cstrArgs);
}
- public static final Object createInstance(String clazzName)
+ public static final Object createInstance(String clazzName, ClassLoader cl)
throws JogampRuntimeException, RuntimeException
{
- return createInstance(clazzName, new Class[0], null);
+ return createInstance(clazzName, cl, new Class[0], null);
}
public static final boolean instanceOf(Object obj, String clazzName) {
@@ -214,12 +214,12 @@ public final class ReflectionUtil {
/**
* @throws JogampRuntimeException if the instance can not be created.
*/
- public static final Object callStaticMethod(String clazzName, String methodName, Class[] argTypes, Object[] args)
+ public static final Object callStaticMethod(String clazzName, ClassLoader cl, String methodName, Class[] argTypes, Object[] args)
throws JogampRuntimeException, RuntimeException
{
Class clazz;
try {
- clazz = getClassImpl(clazzName, true);
+ clazz = getClassImpl(clazzName, true, cl);
} catch (ClassNotFoundException ex) {
throw new JogampRuntimeException(clazzName + " not available", ex);
}
diff --git a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java
index f0be20f..6a73c0a 100644
--- a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java
+++ b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java
@@ -44,12 +44,35 @@ import java.io.PrintStream;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
/**
* Superclass for all generated ProcAddressTables.
+ *
+ * A ProcAddressTable is a cache of pointers to the dynamically-linkable C
+ * functions this autogenerated Java binding has exposed. Some
+ * libraries such as OpenGL, OpenAL and others define function pointer
+ * signatures rather than statically linkable entry points for the
+ * purposes of being able to query at run-time whether a particular
+ * extension is available. This table acts as a cache of these
+ * function pointers. Each function pointer is typically looked up at
+ * run-time by a platform-dependent mechanism such as dlsym(),
+ * wgl/glXGetProcAddress(), or alGetProcAddress(). If the field containing the function
+ * pointer is 0, the function is considered to be unavailable and can
+ * not be called.
+ *
* @author Kenneth Russel
* @author Michael Bien
* @author Sven Gothel
+ *
+ * @see FunctionAddressResolver
+ * @see DynamicLookupHelper
*/
public abstract class ProcAddressTable {
@@ -82,50 +105,31 @@ public abstract class ProcAddressTable {
this.resolver = resolver;
}
+
/**
- * Returns the address for the given function name.
- * @throws RuntimeException if the Table has not been initialized yet.
+ * Resets the complete table.
*/
- public abstract long getAddressFor(String functionName);
-
-
public void reset(DynamicLookupHelper lookup) throws RuntimeException {
+
if(null==lookup) {
throw new RuntimeException("Passed null DynamicLookupHelper");
}
- Class tableClass = getClass();
- Field[] fields = tableClass.getFields();
PrintStream dout = getDebugOutStream();
if (DEBUG) {
- dout.println("ProcAddressTable.reset(" + getClass().getName() + ")");
+ dout.println(getClass().getName()+".reset()");
}
- for (int i = 0; i < fields.length; ++i) {
- String addressFieldName = fields[i].getName();
- if (!addressFieldName.startsWith(PROCADDRESS_VAR_PREFIX)) {
- // not a proc address variable
- continue;
- }
- int startOfMethodName = PROCADDRESS_VAR_PREFIX.length();
- String funcName = addressFieldName.substring(startOfMethodName);
- try {
- Field addressField = fields[i];
- assert (addressField.getType() == Long.TYPE);
-
- long newProcAddress = resolver.resolve(funcName, lookup);
- // set the current value of the proc address variable in the table object
- addressField.setLong(this, newProcAddress);
- if (DEBUG) {
- dout.println(" " + addressField.getName() + " -> 0x" + Long.toHexString(newProcAddress));
- }
- } catch (Exception e) {
- throw new RuntimeException("Can not get proc address for method \""
- + funcName + "\": Couldn't set value of field \"" + addressFieldName
- + "\" in class " + tableClass.getName(), e);
+ Field[] fields = getClass().getFields();
+ for (int i = 0; i < fields.length; ++i) {
+ String fieldName = fields[i].getName();
+ if (isAddressField(fieldName)) {
+ String funcName = fieldToFunctionName(fieldName);
+ setEntry(fields[i], funcName, lookup);
}
}
+
if (DEBUG) {
dout.flush();
if (DEBUG_PREFIX != null) {
@@ -134,6 +138,46 @@ public abstract class ProcAddressTable {
}
}
+ /**
+ * Initializes the mapping for a single function.
+ * @throws IllegalArgumentException if this function is not in this table.
+ */
+ public void initEntry(String name, DynamicLookupHelper lookup) {
+ Field field = fieldForFunction(name);
+ setEntry(field, name, lookup);
+ }
+
+ protected void setEntry(Field addressField, String funcName, DynamicLookupHelper lookup) {
+ try {
+ assert (addressField.getType() == Long.TYPE);
+ long newProcAddress = resolver.resolve(funcName, lookup);
+ // set the current value of the proc address variable in the table object
+ addressField.setLong(this, newProcAddress);
+ if (DEBUG) {
+ getDebugOutStream().println(" " + addressField.getName() + " -> 0x" + Long.toHexString(newProcAddress));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Can not get proc address for method \""
+ + funcName + "\": Couldn't set value of field \"" + addressField, e);
+ }
+ }
+
+ protected String fieldToFunctionName(String addressFieldName) {
+ return addressFieldName.substring(PROCADDRESS_VAR_PREFIX.length());
+ }
+
+ protected Field fieldForFunction(String name) {
+ try {
+ return getClass().getField(PROCADDRESS_VAR_PREFIX + name);
+ } catch (NoSuchFieldException ex) {
+ throw new IllegalArgumentException(getClass().getName() +" has no entry for the function '"+name+"'.", ex);
+ }
+ }
+
+ protected boolean isAddressField(String fieldName) {
+ return fieldName.startsWith(PROCADDRESS_VAR_PREFIX);
+ }
+
protected static PrintStream getDebugOutStream() {
PrintStream out = null;
if (DEBUG) {
@@ -152,6 +196,79 @@ public abstract class ProcAddressTable {
return out;
}
+ /**
+ * Returns this table as map with the function name as key and the address as value.
+ */
+ public Map/*<String, Long>*/ toMap() {
+
+ SortedMap map = new TreeMap();
+
+ Field[] fields = getClass().getFields();
+ try {
+ for (int i = 0; i < fields.length; ++i) {
+ String addressFieldName = fields[i].getName();
+ if (isAddressField(addressFieldName)) {
+ map.put(fieldToFunctionName(addressFieldName), fields[i].get(this));
+ }
+ }
+ } catch (IllegalArgumentException ex) {
+ throw new RuntimeException(ex);
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ return map;
+ }
+
+ /**
+ * Returns true only if non null function pointer to this function exists.
+ */
+ public boolean isFunctionAvailable(String functionName) {
+ try{
+ return getAddressFor(functionName) != 0;
+ }catch (IllegalArgumentException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * This is a convenience method to get (by name) the native function
+ * pointer for a given function. It lets you avoid having to
+ * manually compute the &quot;{@link #PROCADDRESS_VAR_PREFIX} + &lt;functionName&gt;&quot;
+ * member variable name and look it up via reflection.
+ *
+ * @throws IllegalArgumentException if this function is not in this table.
+ */
+ public long getAddressFor(String functionName) {
+ Field addressField = fieldForFunction(functionName);
+ try {
+ return addressField.getLong(this);
+ } catch (IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Returns all functions pointing to null.
+ */
+ public Set/*<String>*/ getNullPointerFunctions() {
+ Map table = toMap();
+ Set nullPointers = new LinkedHashSet();
+ for (Iterator it = table.entrySet().iterator(); it.hasNext();) {
+ Map.Entry entry = (Entry) it.next();
+ long address = ((Long)entry.getValue()).longValue();
+ if(address == 0) {
+ nullPointers.add(entry.getKey());
+ }
+ }
+ return nullPointers;
+ }
+
+// @Override
+ public String toString() {
+ return getClass().getName()+""+toMap();
+ }
+
private static class One2OneResolver implements FunctionAddressResolver {
public long resolve(String name, DynamicLookupHelper lookup) {
diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java
index 2a51a64..c7156c3 100644
--- a/src/java/com/sun/gluegen/JavaEmitter.java
+++ b/src/java/com/sun/gluegen/JavaEmitter.java
@@ -1279,8 +1279,8 @@ public class JavaEmitter implements GlueEmitter {
if (targetType.isVoid()) {
return JavaType.createForVoidPointer();
} else if (targetType.isInt()) {
- // size_t is always a PointerBuffer since size is arch dependent
- if ("size_t".equals(targetType.getName())) {
+ // size_t and intptr_t is always a PointerBuffer since size is arch dependent
+ if ("size_t".equals(targetType.getName()) || "intptr_t".equals(targetType.getName())) {
return JavaType.forNIOPointerBufferClass();
}
switch ((int) targetType.getSize(curMachDesc)) {
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
index aa71495..9094f14 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
@@ -209,12 +209,16 @@ public class ProcAddressEmitter extends JavaEmitter {
}
protected void generateModifiedEmitters(CMethodBindingEmitter baseCEmitter, List<FunctionEmitter> emitters) {
+
+ FunctionSymbol cSymbol = baseCEmitter.getBinding().getCSymbol();
+
// 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());
+ boolean callThroughProcAddress = needsProcAddressWrapper(cSymbol);
+ boolean forceProcAddress = getProcAddressConfig().forceProcAddressGen(cSymbol.getName());
+
String forcedCallingConvention = null;
if (forceProcAddress) {
- forcedCallingConvention = getProcAddressConfig().getLocalProcAddressCallingConvention(baseCEmitter.getBinding().getCSymbol().getName());
+ forcedCallingConvention = getProcAddressConfig().getLocalProcAddressCallingConvention(cSymbol.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
@@ -223,11 +227,9 @@ 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,
- forceProcAddress,
- forcedCallingConvention,
- this);
+ ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter(
+ baseCEmitter, callThroughProcAddress, forceProcAddress, forcedCallingConvention, this);
+
MessageFormat exp = baseCEmitter.getReturnValueCapacityExpression();
if (exp != null) {
res.setReturnValueCapacityExpression(exp);
@@ -289,9 +291,7 @@ public class ProcAddressEmitter extends JavaEmitter {
if (implPackageName == null) {
implPackageName = getImplPackageName();
}
- String jImplRoot =
- getJavaOutputDir() + File.separator
- + CodeGenUtils.packageAsPath(implPackageName);
+ String jImplRoot = getJavaOutputDir() + File.separator + CodeGenUtils.packageAsPath(implPackageName);
tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
emittedTableEntries = new HashSet<String>();
@@ -303,24 +303,14 @@ public class ProcAddressEmitter extends JavaEmitter {
for (String imporT : getConfig().imports()) {
tableWriter.println("import " + imporT + ";");
}
+ tableWriter.println("import " + ProcAddressTable.class.getName() + ";");
tableWriter.println();
tableWriter.println("/**");
- tableWriter.println(" * This table is a cache of pointers to the dynamically-linkable C");
- tableWriter.println(" * functions this autogenerated Java binding has exposed. Some");
- tableWriter.println(" * libraries such as OpenGL, OpenAL and others define function pointer");
- tableWriter.println(" * signatures rather than statically linkable entry points for the");
- tableWriter.println(" * purposes of being able to query at run-time whether a particular");
- tableWriter.println(" * extension is available. This table acts as a cache of these");
- tableWriter.println(" * function pointers. Each function pointer is typically looked up at");
- tableWriter.println(" * run-time by a platform-dependent mechanism such as dlsym(),");
- tableWriter.println(" * wgl/glXGetProcAddress(), or alGetProcAddress(). The associated");
- tableWriter.println(" * autogenerated Java and C code accesses the fields in this table to");
- tableWriter.println(" * call the various functions. If the field containing the function");
- tableWriter.println(" * pointer is 0, the function is considered to be unavailable and can");
- tableWriter.println(" * not be called.");
+ tableWriter.println(" * This table is a cache of pointers to the dynamically-linkable C library.");
+ tableWriter.println(" * @see " + ProcAddressTable.class.getSimpleName());
tableWriter.println(" */");
- tableWriter.println("public class " + tableClassName + " extends "+ ProcAddressTable.class.getName() + " {");
+ tableWriter.println("public class " + tableClassName + " extends "+ ProcAddressTable.class.getSimpleName() + " {");
tableWriter.println();
for (String string : getProcAddressConfig().getForceProcAddressGen()) {
@@ -336,39 +326,9 @@ public class ProcAddressEmitter extends JavaEmitter {
}
protected void endProcAddressTable() throws Exception {
- PrintWriter w = tableWriter;
-
- w.println(" /**");
- w.println(" * This is a convenience method to get (by name) the native function");
- w.println(" * pointer for a given function. It lets you avoid having to");
- w.println(" * manually compute the &quot;" + PROCADDRESS_VAR_PREFIX + " + ");
- w.println(" * &lt;functionName&gt;&quot; member variable name and look it up via");
- w.println(" * reflection; it also will throw an exception if you try to get the");
- w.println(" * address of an unknown function, or one that is statically linked");
- w.println(" * and therefore does not have a function pointer in this table.");
- w.println(" *");
- w.println(" * @throws RuntimeException if the function pointer was not found in");
- w.println(" * this table, either because the function was unknown or because");
- w.println(" * it was statically linked.");
- w.println(" */");
- w.println(" public long getAddressFor(String functionName) {");
- w.println(" String addressFieldName = PROCADDRESS_VAR_PREFIX + functionName;");
- w.println(" try { ");
- w.println(" java.lang.reflect.Field addressField = getClass().getField(addressFieldName);");
- w.println(" return addressField.getLong(this);");
- w.println(" } catch (Exception e) {");
- w.println(" // The user is calling a bogus function or one which is not");
- w.println(" // runtime linked");
- w.println(" throw new RuntimeException(");
- w.println(" \"WARNING: Address query failed for \\\"\" + functionName +");
- w.println(" \"\\\"; it's either statically linked or is not a known \" +");
- w.println(" \"function\", e);");
- w.println(" } ");
- w.println(" }");
-
- w.println("} // end of class " + tableClassName);
- w.flush();
- w.close();
+ tableWriter.println("} // end of class " + tableClassName);
+ tableWriter.flush();
+ tableWriter.close();
}
protected void emitProcAddressTableEntryForString(String str) {
diff --git a/test/junit/com/sun/gluegen/BasicProcAddressEmitterTest.java b/test/junit/com/sun/gluegen/BasicProcAddressEmitterTest.java
new file mode 100644
index 0000000..cdd8bd0
--- /dev/null
+++ b/test/junit/com/sun/gluegen/BasicProcAddressEmitterTest.java
@@ -0,0 +1,68 @@
+package com.sun.gluegen;
+
+import com.sun.gluegen.procaddress.ProcAddressEmitter;
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.AfterClass;
+import org.junit.Test;
+import static java.util.Arrays.*;
+import static com.sun.gluegen.BuildUtil.*;
+import static org.junit.Assert.*;
+
+/**
+ * Basic test using ProcAddressEmitter.
+ * @author Michael Bien
+ */
+public class BasicProcAddressEmitterTest {
+
+ @Test
+ public void generateBindingTest() {
+ generate("dyntest", "test", ProcAddressEmitter.class.getName());
+ }
+
+ /**
+ * fails if ant script fails (which is a good thing).
+ * executeTarget throws RuntimeException on failure
+ */
+ @Test
+ public void compileJavaTest() {
+ compileJava();
+ }
+
+ /*
+ * fails if ant script fails (which is a good thing)
+ * executeTarget throws RuntimeException on failure
+ */
+ @Test
+ public void compileNativesTest() {
+ compileNatives();
+ }
+
+ @Test
+ public void renameTest() throws Exception {
+
+ Class<?> binding = Class.forName("test.DynBindingTest");
+ Class<?> table = Class.forName("test.Table");
+
+ Field[] fields = table.getDeclaredFields();
+
+
+ Set<String> expected = new HashSet<String>(
+ asList("arrayTest", "bufferTest", "pbTest", "manyBuffersTest", "mixedTest", "doubleTest"));
+
+ for (Field field : fields) {
+ System.out.println("address field: "+field);
+
+ String function = field.getName().substring("_addressoff_".length()-1);
+ assertTrue("unexpected field: '"+function+"'",expected.contains(function));
+ }
+
+ }
+
+ @AfterClass
+ public static void tearDown() {
+// cleanGeneratedFiles();
+ }
+
+}
diff --git a/test/junit/com/sun/gluegen/BuildUtil.java b/test/junit/com/sun/gluegen/BuildUtil.java
index 35dc0c1..0658893 100644
--- a/test/junit/com/sun/gluegen/BuildUtil.java
+++ b/test/junit/com/sun/gluegen/BuildUtil.java
@@ -109,14 +109,22 @@ public final class BuildUtil {
}
public static void generate(String bindingName) {
+ generate(bindingName, JavaEmitter.class.getName());
+// generate(bindingName, DebugEmitter.class.getName());
+ }
+
+ public static void generate(String bindingName, String emitter) {
+ generate(bindingName, bindingName, emitter);
+ }
+ public static void generate(String bindingName, String header, String emitter) {
- out.println("generate binding: " + bindingName);
+ out.println("generate binding to '" + bindingName+"' using '"+emitter+"'");
GlueGen.main( "-I"+path,
"-O"+testOutput+"/gensrc",
- // "-Ecom.sun.gluegen.DebugEmitter",
+ "-E"+emitter,
"-C"+path+"/"+bindingName+".cfg",
- path+"/"+bindingName+".h" );
+ path+"/"+header+".h" );
out.println("done");
}
diff --git a/test/junit/com/sun/gluegen/dyntest.cfg b/test/junit/com/sun/gluegen/dyntest.cfg
new file mode 100644
index 0000000..60b8764
--- /dev/null
+++ b/test/junit/com/sun/gluegen/dyntest.cfg
@@ -0,0 +1,25 @@
+Package test
+Style AllStatic
+JavaClass DynBindingTest
+JavaOutputDir java
+NativeOutputDir native
+
+CustomCCode #include "test.h"
+
+Import com.jogamp.common.nio.*
+
+
+EmitProcAddressTable true
+ProcAddressTableClassName Table
+GetProcAddressTableExpr table
+ProcAddressNameExpr $UpperCase(arg)
+
+ForceProcAddressGen __ALL__
+
+CustomJavaCode DynBindingTest private final static Table table;
+CustomJavaCode DynBindingTest static {
+CustomJavaCode DynBindingTest table = new Table();
+CustomJavaCode DynBindingTest //table.reset();
+CustomJavaCode DynBindingTest }
+
+RenameJavaMethod arrayTest fancyArrayTest \ No newline at end of file