aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/games/gluegen
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2003-07-03 00:09:30 +0000
committerKenneth Russel <[email protected]>2003-07-03 00:09:30 +0000
commit93d272a0525ec57aa3cd584f15cde6cf2a637e0c (patch)
tree3d6c9f2a305539d26c7449566bbb0d72bf74b12c /src/net/java/games/gluegen
parent37d90a0da397a1958fb101051170a60f871fb8cc (diff)
Added pbuffer support to JOGL on X11; HWShadowmapsSimple and
ProceduralTexturePhysics demos are now working on Linux with the appropriate hardware. Moved core GLX routines out of the public GLX interface; this allowed XVisualInfo (and the new GLXFBConfig) to be removed from the public API. Added support to GlueGen for returning arrays of pointers as arrays of StructAccessors in Java and for choosing the typedef name for a pointer-to-struct if the struct itself does not have a typedef name. Added support to GLEmitter to emit ProcAddressTables under arbitrary names and to support arbitrary mechanisms for fetching those tables. Made GLU (on all platforms) and GLX (on X11) be dynamically linked. Refactored ProcAddressTable filling to be mostly shared code. Tested changes on Linux, Mac OS X and Windows. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@17 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/net/java/games/gluegen')
-rw-r--r--src/net/java/games/gluegen/CMethodBindingEmitter.java210
-rw-r--r--src/net/java/games/gluegen/DebugEmitter.java9
-rw-r--r--src/net/java/games/gluegen/GlueEmitter.java8
-rw-r--r--src/net/java/games/gluegen/GlueGen.java21
-rw-r--r--src/net/java/games/gluegen/JavaConfiguration.java28
-rw-r--r--src/net/java/games/gluegen/JavaEmitter.java69
-rw-r--r--src/net/java/games/gluegen/JavaMethodBindingEmitter.java2
-rw-r--r--src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java13
-rw-r--r--src/net/java/games/gluegen/JavaType.java55
-rw-r--r--src/net/java/games/gluegen/MethodBinding.java5
-rw-r--r--src/net/java/games/gluegen/ReferencedStructs.java13
-rw-r--r--src/net/java/games/gluegen/cgram/types/PointerType.java4
-rw-r--r--src/net/java/games/gluegen/opengl/BuildComposablePipeline.java2
-rw-r--r--src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java16
-rw-r--r--src/net/java/games/gluegen/opengl/GLEmitter.java95
-rw-r--r--src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java11
-rw-r--r--src/net/java/games/gluegen/runtime/ProcAddressHelper.java46
17 files changed, 491 insertions, 116 deletions
diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java
index 45035f640..763fe6695 100644
--- a/src/net/java/games/gluegen/CMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java
@@ -50,6 +50,10 @@ public class CMethodBindingEmitter extends FunctionEmitter
{
protected static final CommentEmitter defaultCommentEmitter =
new DefaultCommentEmitter();
+
+ protected static final String arrayResLength = "_array_res_length";
+ protected static final String arrayRes = "_array_res";
+ protected static final String arrayIdx = "_array_idx";
private MethodBinding binding;
@@ -89,6 +93,12 @@ public class CMethodBindingEmitter extends FunctionEmitter
*/
private MessageFormat returnValueCapacityExpression = null;
+ /**
+ * Length of the returned array. Is ignored if
+ * binding.getJavaReturnType().isArray() is false.
+ */
+ private MessageFormat returnValueLengthExpression = null;
+
// Note: the VC++ 6.0 compiler emits hundreds of warnings when the
// (necessary) null-checking code is enabled. This appears to just
// be a compiler bug, but would be good to track down exactly why it
@@ -168,6 +178,49 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
/**
+ * Get the expression for the length of the returned array
+ */
+ public final MessageFormat getReturnValueLengthExpression()
+ {
+ return returnValueLengthExpression;
+ }
+
+ /**
+ * If this function returns an array, sets the expression for the
+ * length of the returned array.
+ *
+ * @param expression a MessageFormat which, when applied to an array
+ * of type String[] that contains each of the arguments names of the
+ * Java-side binding, returns an expression that will (when compiled
+ * by a C compiler) evaluate to an integer-valued expression. The
+ * value of this expression is the length of the array returned from
+ * this method.
+ *
+ * @throws IllegalArgumentException if the <code>
+ * binding.getJavaReturnType().isNIOBuffer() == false
+ * </code>
+ */
+ public final void setReturnValueLengthExpression(MessageFormat expression)
+ {
+ returnValueLengthExpression = expression;
+
+ if (!binding.getJavaReturnType().isArray())
+ {
+ throw new IllegalArgumentException(
+ "Cannot specify return value length for a method that does not " +
+ "return an array: \"" + binding + "\"");
+ }
+ }
+
+ /**
+ * Returns the List of Strings containing declarations for temporary
+ * C variables to be assigned to after the underlying function call.
+ */
+ public final List/*<String>*/ getTemporaryCVariableDeclarations() {
+ return temporaryCVariableDeclarations;
+ }
+
+ /**
* Sets up a List of Strings containing declarations for temporary C
* variables to be assigned to after the underlying function call. A
* null argument indicates that no manual declarations are to be made.
@@ -177,6 +230,16 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
/**
+ * Returns the List of Strings containing assignments for temporary
+ * C variables which are made after the underlying function call. A
+ * null argument indicates that no manual assignments are to be
+ * made.
+ */
+ public final List/*<String>*/ getTemporaryCVariableAssignments() {
+ return temporaryCVariableAssignments;
+ }
+
+ /**
* Sets up a List of Strings containing assignments for temporary C
* variables which are made after the underlying function call. A
* null argument indicates that no manual assignments are to be made.
@@ -340,8 +403,6 @@ public class CMethodBindingEmitter extends FunctionEmitter
Type cReturnType = binding.getCReturnType();
JavaType javaReturnType = binding.getJavaReturnType();
- String arrayResLength = "_array_res_length";
- String arrayRes = "_array_res";
String capitalizedComponentType = null;
if (!cReturnType.isVoid()) {
writer.print(" ");
@@ -349,24 +410,36 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(binding.getCSymbol().getReturnType().getName(true));
writer.println(" _res;");
if (javaReturnType.isArray()) {
- writer.print(" int ");
- writer.print(arrayResLength);
- writer.println(";");
+ if (javaReturnType.isNIOByteBufferArray()) {
+ writer.print(" int ");
+ writer.print(arrayResLength);
+ writer.println(";");
+ writer.print(" int ");
+ writer.print(arrayIdx);
+ writer.println(";");
+ writer.print(" jobjectArray ");
+ writer.print(arrayRes);
+ writer.println(";");
+ } else {
+ writer.print(" int ");
+ writer.print(arrayResLength);
+ writer.println(";");
- Class componentType = javaReturnType.getJavaClass().getComponentType();
- if (componentType.isArray()) {
- throw new RuntimeException("Multi-dimensional arrays not supported yet");
- }
+ Class componentType = javaReturnType.getJavaClass().getComponentType();
+ if (componentType.isArray()) {
+ throw new RuntimeException("Multi-dimensional arrays not supported yet");
+ }
- String javaTypeName = componentType.getName();
- capitalizedComponentType =
- "" + Character.toUpperCase(javaTypeName.charAt(0)) + javaTypeName.substring(1);
- String javaArrayTypeName = "j" + javaTypeName + "Array";
- writer.print(" ");
- writer.print(javaArrayTypeName);
- writer.print(" ");
- writer.print(arrayRes);
- writer.println(";");
+ String javaTypeName = componentType.getName();
+ capitalizedComponentType =
+ "" + Character.toUpperCase(javaTypeName.charAt(0)) + javaTypeName.substring(1);
+ String javaArrayTypeName = "j" + javaTypeName + "Array";
+ writer.print(" ");
+ writer.print(javaArrayTypeName);
+ writer.print(" ");
+ writer.print(arrayRes);
+ writer.println(";");
+ }
}
}
}
@@ -568,6 +641,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
+ } else if (javaArgType.isArrayOfCompoundTypeWrappers()) {
+
+ // FIXME
+ throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
+
}
}
}
@@ -696,6 +774,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
+ } else if (javaArgType.isArrayOfCompoundTypeWrappers()) {
+
+ // FIXME
+ throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
+
}
}
}
@@ -826,35 +909,63 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(" if (_res == NULL) return NULL;");
writer.println(" return (*env)->NewStringUTF(env, _res);");
} else if (javaReturnType.isArray()) {
- // FIXME: must have user provide length of array in .cfg file
- // by providing a constant value, input parameter, or
- // expression which computes the array size (already present
- // as ReturnValueCapacity, not yet implemented / tested here)
-
- throw new RuntimeException(
- "Could not emit native code for function \"" + binding +
- "\": array return values for non-char types not implemented yet");
-
- // FIXME: This is approximately what will be required here
- //
- //writer.print(" ");
- //writer.print(arrayRes);
- //writer.print(" = (*env)->New");
- //writer.print(capitalizedComponentType);
- //writer.print("Array(env, ");
- //writer.print(arrayResLength);
- //writer.println(");");
- //writer.print(" (*env)->Set");
- //writer.print(capitalizedComponentType);
- //writer.print("ArrayRegion(env, ");
- //writer.print(arrayRes);
- //writer.print(", 0, ");
- //writer.print(arrayResLength);
- //writer.println(", _res);");
- //writer.print(" return ");
- //writer.print(arrayRes);
- //writer.println(";");
-
+ if (javaReturnType.isNIOByteBufferArray()) {
+ writer.println(" if (_res == NULL) return NULL;");
+ if (returnValueLengthExpression == null) {
+ throw new RuntimeException("Error while generating C code: no length specified for array returned from function " +
+ binding);
+ }
+ String[] argumentNames = new String[binding.getNumArguments()];
+ for (int i = 0; i < binding.getNumArguments(); i++) {
+ argumentNames[i] = binding.getArgumentName(i);
+ }
+ writer.println(" " + arrayResLength + " = " + returnValueLengthExpression.format(argumentNames) + ";");
+ writer.println(" " + arrayRes + " = (*env)->NewObjectArray(env, " + arrayResLength + ", (*env)->FindClass(env, \"java/nio/ByteBuffer\"), NULL);");
+ writer.println(" for (" + arrayIdx + " = 0; " + arrayIdx + " < " + arrayResLength + "; " + arrayIdx + "++) {");
+ Type retType = binding.getCSymbol().getReturnType();
+ Type baseType;
+ if (retType.isPointer()) {
+ baseType = retType.asPointer().getTargetType().asPointer().getTargetType();
+ } else {
+ baseType = retType.asArray().getElementType().asPointer().getTargetType();
+ }
+ int sz = baseType.getSize();
+ if (sz < 0)
+ sz = 0;
+ writer.println(" (*env)->SetObjectArrayElement(env, " + arrayRes + ", " + arrayIdx +
+ ", (*env)->NewDirectByteBuffer(env, _res[" + arrayIdx + "], " + sz + "));");
+ writer.println(" }");
+ writer.println(" return " + arrayRes + ";");
+ } else {
+ // FIXME: must have user provide length of array in .cfg file
+ // by providing a constant value, input parameter, or
+ // expression which computes the array size (already present
+ // as ReturnValueCapacity, not yet implemented / tested here)
+
+ throw new RuntimeException(
+ "Could not emit native code for function \"" + binding +
+ "\": array return values for non-char types not implemented yet");
+
+ // FIXME: This is approximately what will be required here
+ //
+ //writer.print(" ");
+ //writer.print(arrayRes);
+ //writer.print(" = (*env)->New");
+ //writer.print(capitalizedComponentType);
+ //writer.print("Array(env, ");
+ //writer.print(arrayResLength);
+ //writer.println(");");
+ //writer.print(" (*env)->Set");
+ //writer.print(capitalizedComponentType);
+ //writer.print("ArrayRegion(env, ");
+ //writer.print(arrayRes);
+ //writer.print(", 0, ");
+ //writer.print(arrayResLength);
+ //writer.println(", _res);");
+ //writer.print(" return ");
+ //writer.print(arrayRes);
+ //writer.println(";");
+ }
}
}
}
@@ -1034,6 +1145,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
throw new RuntimeException("Unsupported pointer type: \"" + cType.getName() + "\"");
}
}
+ else if (javaType.isArrayOfCompoundTypeWrappers())
+ {
+ // FIXME
+ throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
+ }
else
{
ptrTypeString = cType.getName();
diff --git a/src/net/java/games/gluegen/DebugEmitter.java b/src/net/java/games/gluegen/DebugEmitter.java
index 677c3e7e6..8618e1576 100644
--- a/src/net/java/games/gluegen/DebugEmitter.java
+++ b/src/net/java/games/gluegen/DebugEmitter.java
@@ -95,8 +95,13 @@ public class DebugEmitter implements GlueEmitter {
TypeDictionary structDictionary,
Map canonMap) {
}
- public void emitStruct(CompoundType t) {
- System.out.println("Referenced type \"" + t.getName() + "\"");
+ public void emitStruct(CompoundType t, String alternateName) {
+ String name = t.getName();
+ if (name == null && alternateName != null) {
+ name = alternateName;
+ }
+
+ System.out.println("Referenced type \"" + name + "\"");
}
public void endStructs() {}
}
diff --git a/src/net/java/games/gluegen/GlueEmitter.java b/src/net/java/games/gluegen/GlueEmitter.java
index 3d55474e0..e816ffc9d 100644
--- a/src/net/java/games/gluegen/GlueEmitter.java
+++ b/src/net/java/games/gluegen/GlueEmitter.java
@@ -93,7 +93,11 @@ public interface GlueEmitter {
public void beginStructs(TypeDictionary typedefDictionary,
TypeDictionary structDictionary,
Map canonMap) throws Exception;
- /** Emit glue code for the given CompoundType. */
- public void emitStruct(CompoundType t) throws Exception;
+ /** Emit glue code for the given CompoundType. alternateName is
+ provided when the CompoundType (e.g. "struct foo_t") has not
+ been typedefed to anything but the type of "pointer to struct
+ foo_t" has (e.g. "typedef struct foo_t {} *Foo"); in this case
+ alternateName would be set to Foo. */
+ public void emitStruct(CompoundType t, String alternateName) throws Exception;
public void endStructs() throws Exception;
}
diff --git a/src/net/java/games/gluegen/GlueGen.java b/src/net/java/games/gluegen/GlueGen.java
index 374611c81..2e5f3421a 100644
--- a/src/net/java/games/gluegen/GlueGen.java
+++ b/src/net/java/games/gluegen/GlueGen.java
@@ -241,20 +241,35 @@ public class GlueGen implements GlueEmitterControls {
System.err.println("WARNING: during forced struct emission: type \"" + name + "\" was not a struct");
} else {
type.visit(referencedStructs);
- }
+ }
}
// Lay out structs
emit.beginStructLayout();
for (Iterator iter = referencedStructs.results(); iter.hasNext(); ) {
- emit.layoutStruct((CompoundType) iter.next());
+ Type t = (Type) iter.next();
+ if (t.isCompound()) {
+ emit.layoutStruct(t.asCompound());
+ } else if (t.isPointer()) {
+ PointerType p = t.asPointer();
+ CompoundType c = p.getTargetType().asCompound();
+ emit.layoutStruct(c);
+ }
}
emit.endStructLayout();
// Emit structs
emit.beginStructs(td, sd, headerParser.getCanonMap());
for (Iterator iter = referencedStructs.results(); iter.hasNext(); ) {
- emit.emitStruct((CompoundType) iter.next());
+ Type t = (Type) iter.next();
+ if (t.isCompound()) {
+ emit.emitStruct(t.asCompound(), null);
+ } else if (t.isPointer()) {
+ PointerType p = t.asPointer();
+ CompoundType c = p.getTargetType().asCompound();
+ assert p.hasTypedefedName() && c.getName() == null : "ReferencedStructs incorrectly recorded pointer type " + p;
+ emit.emitStruct(c, p.getName());
+ }
}
emit.endStructs();
diff --git a/src/net/java/games/gluegen/JavaConfiguration.java b/src/net/java/games/gluegen/JavaConfiguration.java
index ecd953480..3950a7014 100644
--- a/src/net/java/games/gluegen/JavaConfiguration.java
+++ b/src/net/java/games/gluegen/JavaConfiguration.java
@@ -105,6 +105,7 @@ public class JavaConfiguration {
private List/*<String>*/ forcedStructs = new ArrayList();
private Map/*<String,List<Integer>>*/ mirroredArgs = new HashMap();
private Map/*<String, String>*/ returnValueCapacities = new HashMap();
+ private Map/*<String, String>*/ returnValueLengths = new HashMap();
private Map/*<String, List<String>>*/ temporaryCVariableDeclarations = new HashMap();
private Map/*<String, List<String>>*/ temporaryCVariableAssignments = new HashMap();
private Map/*<String,List<String>>*/ extendedInterfaces = new HashMap();
@@ -288,7 +289,9 @@ public class JavaConfiguration {
/** Provides a Java MessageFormat expression indicating the number
of elements in the returned array from the specified function
- name as defined by the ReturnsArray directive. */
+ name. Indicates that the given return value, which must be a
+ pointer to a CompoundType, is actually an array of the
+ CompoundType rather than a pointer to a single object. */
public String returnedArrayLength(String functionName) {
return (String) returnedArrayLengths.get(functionName);
}
@@ -378,6 +381,13 @@ public class JavaConfiguration {
return (String) returnValueCapacities.get(functionName);
}
+ /** Returns a MessageFormat string of the C expression calculating
+ the length of the array being returned from a native method, or
+ null if no expression has been specified. */
+ public String returnValueLength(String functionName) {
+ return (String) returnValueLengths.get(functionName);
+ }
+
/** Returns a List of Strings of expressions declaring temporary C
variables in the glue code for the specified function. */
public List/*<String>*/ temporaryCVariableDeclarations(String functionName) {
@@ -582,6 +592,10 @@ public class JavaConfiguration {
readReturnValueCapacity(tok, filename, lineNo);
// Warning: make sure delimiters are reset at the top of this loop
// because ReturnValueCapacity changes them.
+ } else if (cmd.equalsIgnoreCase("ReturnValueLength")) {
+ readReturnValueLength(tok, filename, lineNo);
+ // Warning: make sure delimiters are reset at the top of this loop
+ // because ReturnValueLength changes them.
} else if (cmd.equalsIgnoreCase("Include")) {
doInclude(tok, file, filename, lineNo);
} else if (cmd.equalsIgnoreCase("IncludeAs")) {
@@ -926,6 +940,18 @@ public class JavaConfiguration {
}
}
+ protected void readReturnValueLength(StringTokenizer tok, String filename, int lineNo) {
+ try {
+ String functionName = tok.nextToken();
+ String restOfLine = tok.nextToken("\n\r\f");
+ restOfLine = restOfLine.trim();
+ returnValueLengths.put(functionName, restOfLine);
+ } catch (NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"ReturnValueLength\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
+
protected void readTemporaryCVariableDeclaration(StringTokenizer tok, String filename, int lineNo) {
try {
String functionName = tok.nextToken();
diff --git a/src/net/java/games/gluegen/JavaEmitter.java b/src/net/java/games/gluegen/JavaEmitter.java
index 228b5aff2..26e2a4f23 100644
--- a/src/net/java/games/gluegen/JavaEmitter.java
+++ b/src/net/java/games/gluegen/JavaEmitter.java
@@ -451,18 +451,26 @@ public class JavaEmitter implements GlueEmitter {
this.canonMap = canonMap;
}
- public void emitStruct(CompoundType structType) throws Exception {
- if (structType.getName() == null) {
+ public void emitStruct(CompoundType structType, String alternateName) throws Exception {
+ String name = structType.getName();
+ if (name == null && alternateName != null) {
+ name = alternateName;
+ }
+
+ if (name == null) {
System.err.println("WARNING: skipping emission of unnamed struct \"" + structType + "\"");
return;
}
- if (cfg.shouldIgnore(structType.getName())) {
+ if (cfg.shouldIgnore(name)) {
return;
}
Type containingCType = canonicalize(new PointerType(machDesc.pointerSizeInBytes(), structType, 0));
JavaType containingType = typeToJavaType(containingCType, false);
+ if (!containingType.isCompoundTypeWrapper()) {
+ return;
+ }
String containingTypeName = containingType.getName();
boolean needsNativeCode = false;
@@ -473,7 +481,7 @@ public class JavaEmitter implements GlueEmitter {
}
}
- String structClassPkg = cfg.packageForStruct(structType.getName());
+ String structClassPkg = cfg.packageForStruct(name);
PrintWriter writer = null;
PrintWriter cWriter = null;
try
@@ -534,7 +542,7 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < structType.getNumFields(); i++) {
Field field = structType.getField(i);
Type fieldType = field.getType();
- if (!cfg.shouldIgnore(structType.getName() + " " + field.getName())) {
+ if (!cfg.shouldIgnore(name + " " + field.getName())) {
if (fieldType.isFunctionPointer()) {
try {
// Emit method call and associated native code
@@ -566,7 +574,7 @@ public class JavaEmitter implements GlueEmitter {
cWriter);
cEmitter.emit();
} catch (Exception e) {
- System.err.println("While processing field " + field + " of type " + structType.getName() + ":");
+ System.err.println("While processing field " + field + " of type " + name + ":");
throw(e);
}
} else if (fieldType.isCompound()) {
@@ -575,7 +583,7 @@ public class JavaEmitter implements GlueEmitter {
// a name?)
if (fieldType.getName() == null) {
throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
- field + "\" in type \"" + structType.getName() + "\")");
+ field + "\" in type \"" + name + "\")");
}
writer.println();
@@ -586,7 +594,7 @@ public class JavaEmitter implements GlueEmitter {
// FIXME: add setter by autogenerating "copyTo" for all compound type wrappers
} else if (fieldType.isArray()) {
- System.err.println("WARNING: Array fields (field \"" + field + "\" of type \"" + structType.getName() +
+ System.err.println("WARNING: Array fields (field \"" + field + "\" of type \"" + name +
"\") not implemented yet");
} else {
JavaType javaType = null;
@@ -594,7 +602,7 @@ public class JavaEmitter implements GlueEmitter {
javaType = typeToJavaType(fieldType, false);
} catch (Exception e) {
System.err.println("Error occurred while creating accessor for field \"" +
- field.getName() + "\" in type \"" + structType.getName() + "\"");
+ field.getName() + "\" in type \"" + name + "\"");
e.printStackTrace();
throw(e);
}
@@ -629,10 +637,6 @@ public class JavaEmitter implements GlueEmitter {
writer.println(" }");
} else {
// FIXME
- String name = structType.getName();
- if (name == null) {
- name = structType.toString();
- }
System.err.println("WARNING: Complicated fields (field \"" + field + "\" of type \"" + name +
"\") not implemented yet");
// throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
@@ -663,6 +667,7 @@ public class JavaEmitter implements GlueEmitter {
String bindingJavaClassName,
PrintWriter output) {
MessageFormat returnValueCapacityFormat = null;
+ MessageFormat returnValueLengthFormat = null;
JavaType javaReturnType = binding.getJavaReturnType();
if (javaReturnType.isNIOBuffer()) {
// See whether capacity has been specified
@@ -670,6 +675,12 @@ public class JavaEmitter implements GlueEmitter {
if (capacity != null) {
returnValueCapacityFormat = new MessageFormat(capacity);
}
+ } else if (javaReturnType.isArray()) {
+ // See whether length has been specified
+ String len = cfg.returnValueLength(binding.getName());
+ if (len != null) {
+ returnValueLengthFormat = new MessageFormat(len);
+ }
}
CMethodBindingEmitter cEmitter;
if (doingImplRoutine) {
@@ -686,6 +697,9 @@ public class JavaEmitter implements GlueEmitter {
if (returnValueCapacityFormat != null) {
cEmitter.setReturnValueCapacityExpression(returnValueCapacityFormat);
}
+ if (returnValueLengthFormat != null) {
+ cEmitter.setReturnValueLengthExpression(returnValueLengthFormat);
+ }
cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName()));
cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName()));
return cEmitter;
@@ -758,12 +772,21 @@ public class JavaEmitter implements GlueEmitter {
throw new RuntimeException("Arrays of compound types not handled yet");
}
// Special cases for known JNI types (in particular for converting jawt.h)
- if (cType.getName() != null &&
- cType.getName().equals("jobject")) {
+ if (t.getName() != null &&
+ t.getName().equals("jobject")) {
return javaType(java.lang.Object.class);
}
- return JavaType.createForCStruct(cfg.renameJavaType(targetType.getName()));
+ String name = targetType.getName();
+ if (name == null) {
+ // Try containing pointer type for any typedefs
+ name = t.getName();
+ if (name == null) {
+ throw new RuntimeException("Couldn't find a proper type name for pointer type " + t);
+ }
+ }
+
+ return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException("Don't know how to convert pointer/array type \"" +
t + "\"");
@@ -775,15 +798,16 @@ public class JavaEmitter implements GlueEmitter {
// Get the target type of the target type (targetType was computer earlier
// as to be a pointer to the target type, so now we need to get its
// target type)
+ Type bottomType;
if (targetType.isPointer()) {
// t is<type>**, targetType is <type>*, we need to get <type>
- targetType = targetType.asPointer().getTargetType();
+ bottomType = targetType.asPointer().getTargetType();
} else {
// t is<type>[][], targetType is <type>[], we need to get <type>
- targetType = targetType.asArray().getElementType();
+ bottomType = targetType.asArray().getElementType();
}
- if (targetType.isInt()) {
- switch (targetType.getSize())
+ if (bottomType.isInt()) {
+ switch (bottomType.getSize())
{
case 1: return javaType(ArrayTypes.byteArrayArrayClass);
// FIXME: handle 2,4,8-byte int types here
@@ -793,10 +817,13 @@ public class JavaEmitter implements GlueEmitter {
"Java type; Currently, the only supported depth=2 " +
"pointer/array integer types are \"char**\" and \"char[][]\"");
}
+ } else if (targetType.isPointer() && (targetType.pointerDepth() == 1)) {
+ // Array of pointers; convert as array of StructAccessors
+ return JavaType.createForCArray(targetType);
} else {
throw new RuntimeException(
"Could not convert C type \"" + t + "\" " +
- "to appropriate Java type; need to add support for " +
+ "to appropriate Java type; need to add more support for " +
"depth=2 pointer/array types with non-integral target " +
"types [debug info: targetType=\"" + targetType + "\"]");
}
diff --git a/src/net/java/games/gluegen/JavaMethodBindingEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingEmitter.java
index 003ea8643..850a2c701 100644
--- a/src/net/java/games/gluegen/JavaMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/JavaMethodBindingEmitter.java
@@ -122,7 +122,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
}
protected String getReturnTypeString(boolean skipArray) {
- if (skipArray || getReturnedArrayLengthExpression() == null) {
+ if (skipArray || (getReturnedArrayLengthExpression() == null && !binding.getJavaReturnType().isArrayOfCompoundTypeWrappers())) {
return binding.getJavaReturnType().getName();
}
return binding.getJavaReturnType().getName() + "[]";
diff --git a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
index 2357e7c38..2ec2723bd 100644
--- a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
+++ b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
@@ -113,6 +113,9 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
returnType.isNIOByteBuffer()) {
writer.println("ByteBuffer _res;");
writer.print(" _res = ");
+ } else if (returnType.isArrayOfCompoundTypeWrappers()) {
+ writer.println("ByteBuffer[] _res;");
+ writer.print(" _res = ");
} else {
writer.print("return ");
}
@@ -205,7 +208,7 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
writer.println(" _tmp.order(ByteOrder.nativeOrder());");
writer.println(" _res.position(0);");
writer.println(" _res.limit(_res.capacity());");
- writer.println(" _retarray[_count] = new " + returnType.getName() + "(_tmp);");
+ writer.println(" _retarray[_count] = new " + getReturnTypeString(true) + "(_tmp);");
writer.println(" }");
writer.print (" return _retarray");
}
@@ -213,6 +216,14 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
writer.println(";");
writer.println(" if (_res == null) return null;");
writer.print(" return _res.order(ByteOrder.nativeOrder())");
+ } else if (returnType.isArrayOfCompoundTypeWrappers()) {
+ writer.println(";");
+ writer.println(" if (_res == null) return null;");
+ writer.println(" " + getReturnTypeString(false) + " _retarray = new " + getReturnTypeString(true) + "[_res.length];");
+ writer.println(" for (int _count = 0; _count < _res.length; _count++) {");
+ writer.println(" _retarray[_count] = new " + getReturnTypeString(true) + "(_res[_count]);");
+ writer.println(" }");
+ writer.print (" return _retarray");
}
writer.println(";");
}
diff --git a/src/net/java/games/gluegen/JavaType.java b/src/net/java/games/gluegen/JavaType.java
index ac42aa0f1..ea771613e 100644
--- a/src/net/java/games/gluegen/JavaType.java
+++ b/src/net/java/games/gluegen/JavaType.java
@@ -39,6 +39,10 @@
package net.java.games.gluegen;
+import java.nio.*;
+
+import net.java.games.gluegen.cgram.types.*;
+
/**
* Describes a java-side representation of a type that is used to represent
* the same data on both the Java-side and C-side during a JNI operation. Also
@@ -47,8 +51,10 @@ package net.java.games.gluegen;
public class JavaType {
private Class clazz; // Primitive types and other types representable as Class objects
private String name; // Types we're generating glue code for (i.e., C structs)
+ private Type elementType; // Element type if this JavaType represents a C array
private static JavaType nioBufferType;
private static JavaType nioByteBufferType;
+ private static JavaType nioByteBufferArrayType;
public boolean equals(Object arg) {
if ((arg == null) || (!(arg instanceof JavaType))) {
@@ -70,14 +76,28 @@ public class JavaType {
return clazz.hashCode();
}
+ /** Creates a JavaType corresponding to the given Java type. This
+ can be used to represent arrays of primitive values or Strings;
+ the emitters understand how to perform proper conversion from
+ the corresponding C type. */
public static JavaType createForClass(Class clazz) {
return new JavaType(clazz);
}
+ /** Creates a JavaType corresponding to the specified C CompoundType
+ name; for example, if "Foo" is supplied, then this JavaType
+ represents a "Foo *" by way of a StructAccessor. */
public static JavaType createForCStruct(String name) {
return new JavaType(name);
}
+ /** Creates a JavaType corresponding to an array of the given
+ element type. This is used to represent arrays of "Foo **" which
+ should be mapped to Foo[] in Java. */
+ public static JavaType createForCArray(Type elementType) {
+ return new JavaType(elementType);
+ }
+
public static JavaType createForVoidPointer() {
return new JavaType();
}
@@ -100,6 +120,14 @@ public class JavaType {
return nioByteBufferType;
}
+ public static JavaType forNIOByteBufferArrayClass() {
+ if (nioByteBufferArrayType == null) {
+ ByteBuffer[] tmp = new ByteBuffer[0];
+ nioByteBufferArrayType = createForClass(tmp.getClass());
+ }
+ return nioByteBufferArrayType;
+ }
+
/**
* Returns the Java Class corresponding to this type. Returns null if this
* object corresponds to a C "void*" type.
@@ -119,6 +147,9 @@ public class JavaType {
}
return clazz.getName();
}
+ if (elementType != null) {
+ return elementType.getName();
+ }
return name;
}
@@ -151,6 +182,10 @@ public class JavaType {
return "jobjectArray /*elements are String*/";
//return "jobjectArray";
}
+ else if (elementType == java.nio.ByteBuffer.class)
+ {
+ return "jobjectArray /*elements are ByteBuffer*/";
+ }
else if (elementType.isArray())
{
// Type is array-of-arrays-of-something
@@ -189,6 +224,10 @@ public class JavaType {
return (clazz == java.nio.ByteBuffer.class);
}
+ public boolean isNIOByteBufferArray() {
+ return (this == nioByteBufferArrayType);
+ }
+
public boolean isString() {
return (clazz == java.lang.String.class);
}
@@ -205,17 +244,16 @@ public class JavaType {
return (clazz == Void.TYPE);
}
- public boolean isObjectType() {
- // FIXME: what about char* -> String conversion?
- return (isNIOBuffer() || isArray());
- }
-
public boolean isCompoundTypeWrapper() {
return (clazz == null && name != null && !isJNIEnv());
}
+ public boolean isArrayOfCompoundTypeWrappers() {
+ return (elementType != null);
+ }
+
public boolean isVoidPointerType() {
- return (clazz == null && name == null);
+ return (clazz == null && name == null && elementType == null);
}
public boolean isJNIEnv() {
@@ -252,6 +290,11 @@ public class JavaType {
this.name = name;
}
+ /** Constructs a type representing an array of C pointers. */
+ private JavaType(Type elementType) {
+ this.elementType = elementType;
+ }
+
/**
* Default constructor; the type is initialized to the equivalent of a
* C-language "void *".
diff --git a/src/net/java/games/gluegen/MethodBinding.java b/src/net/java/games/gluegen/MethodBinding.java
index 9cdcd4b0b..b8f0eefdf 100644
--- a/src/net/java/games/gluegen/MethodBinding.java
+++ b/src/net/java/games/gluegen/MethodBinding.java
@@ -174,7 +174,8 @@ public class MethodBinding {
public boolean needsBody() {
if (!computedNeedsBody) {
if (javaReturnType.isCompoundTypeWrapper() ||
- javaReturnType.isNIOByteBuffer()) {
+ javaReturnType.isNIOByteBuffer() ||
+ javaReturnType.isArrayOfCompoundTypeWrappers()) {
// Needs wrapping and/or setting of byte order (neither of
// which can be done easily from native code)
needsBody = true;
@@ -204,6 +205,8 @@ public class MethodBinding {
binding.thisPointerIndex = thisPointerIndex;
if (javaReturnType.isCompoundTypeWrapper()) {
binding.setJavaReturnType(JavaType.forNIOByteBufferClass());
+ } else if (javaReturnType.isArrayOfCompoundTypeWrappers()) {
+ binding.setJavaReturnType(JavaType.forNIOByteBufferArrayClass());
} else {
binding.setJavaReturnType(javaReturnType);
}
diff --git a/src/net/java/games/gluegen/ReferencedStructs.java b/src/net/java/games/gluegen/ReferencedStructs.java
index 1b3b75198..4a7a8aadf 100644
--- a/src/net/java/games/gluegen/ReferencedStructs.java
+++ b/src/net/java/games/gluegen/ReferencedStructs.java
@@ -54,7 +54,18 @@ public class ReferencedStructs implements TypeVisitor {
}
public void visitType(Type t) {
- if (t.isCompound()) {
+ if (t.isPointer()) {
+ PointerType p = t.asPointer();
+ if (p.hasTypedefedName()) {
+ CompoundType c = p.getTargetType().asCompound();
+ if (c != null && c.getName() == null) {
+ // This otherwise-unnamed CompoundType is referred to by a
+ // PointerType that has a typedef name. Assume that it is
+ // referred to in the glue code and emit it.
+ results.add(p);
+ }
+ }
+ } else if (t.isCompound()) {
results.add(t);
}
}
diff --git a/src/net/java/games/gluegen/cgram/types/PointerType.java b/src/net/java/games/gluegen/cgram/types/PointerType.java
index 62bfe9c1a..64acbade4 100644
--- a/src/net/java/games/gluegen/cgram/types/PointerType.java
+++ b/src/net/java/games/gluegen/cgram/types/PointerType.java
@@ -100,6 +100,10 @@ public class PointerType extends Type {
}
}
+ public boolean hasTypedefedName() {
+ return hasTypedefedName;
+ }
+
public PointerType asPointer() { return this; }
public Type getTargetType() { return targetType; }
diff --git a/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java b/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java
index 47476a54c..c6ac77c7b 100644
--- a/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/net/java/games/gluegen/opengl/BuildComposablePipeline.java
@@ -209,7 +209,7 @@ public class BuildComposablePipeline
{
output.print(" public ");
output.print(' ');
- output.print(m.getReturnType().getName());
+ output.print(JavaType.createForClass(m.getReturnType()).getName());
output.print(' ');
output.print(m.getName());
output.print('(');
diff --git a/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java b/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
index cd0554dc3..2a1559e52 100644
--- a/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
+++ b/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
@@ -68,6 +68,15 @@ public class CGLPAWrapperEmitter extends CMethodBindingEmitter
methodToWrap.getIsJavaMethodStatic(),
methodToWrap.getDefaultOutput()
);
+
+ if (methodToWrap.getReturnValueCapacityExpression() != null) {
+ setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression());
+ }
+ if (methodToWrap.getReturnValueLengthExpression() != null) {
+ setReturnValueLengthExpression(methodToWrap.getReturnValueLengthExpression());
+ }
+ setTemporaryCVariableDeclarations(methodToWrap.getTemporaryCVariableDeclarations());
+ setTemporaryCVariableAssignments (methodToWrap.getTemporaryCVariableAssignments ());
setCommentEmitter(defaultCommentEmitter);
}
@@ -192,6 +201,13 @@ public class CGLPAWrapperEmitter extends CMethodBindingEmitter
writer.println(");");
}
+ protected String jniMangle(MethodBinding binding) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(super.jniMangle(binding));
+ jniMangle(Long.TYPE, buf);
+ return buf.toString();
+ }
+
/** This class emits the comment for the wrapper method */
private static class CGLPAWrapperCommentEmitter extends CMethodBindingEmitter.DefaultCommentEmitter {
protected void emitBeginning(FunctionEmitter methodEmitter, PrintWriter writer) {
diff --git a/src/net/java/games/gluegen/opengl/GLEmitter.java b/src/net/java/games/gluegen/opengl/GLEmitter.java
index 27cc07e2c..f6e26fd3b 100644
--- a/src/net/java/games/gluegen/opengl/GLEmitter.java
+++ b/src/net/java/games/gluegen/opengl/GLEmitter.java
@@ -44,6 +44,7 @@ import java.text.MessageFormat;
import java.util.*;
import net.java.games.gluegen.*;
import net.java.games.gluegen.cgram.types.*;
+import net.java.games.gluegen.runtime.*;
/**
* A subclass of JavaEmitter that modifies the normal emission of C and Java
@@ -52,11 +53,12 @@ import net.java.games.gluegen.cgram.types.*;
*/
public class GLEmitter extends JavaEmitter
{
- public static final String PROCADDRESS_VAR_PREFIX = "_addressof_";
+ public static final String PROCADDRESS_VAR_PREFIX = ProcAddressHelper.PROCADDRESS_VAR_PREFIX;
protected static final String WRAP_PREFIX = "dispatch_";
private TypeDictionary typedefDictionary;
private PrintWriter tableWriter;
- private String tableClassName = "ProcAddressTable";
+ private String tableClassPackage;
+ private String tableClassName;
private int numProcAddressEntries;
public void beginFunctions(TypeDictionary typedefDictionary,
@@ -70,7 +72,7 @@ public class GLEmitter extends JavaEmitter
cWriter().println();
}
- if (((GLConfiguration)getConfig()).emitProcAddressTable())
+ if (getGLConfig().emitProcAddressTable())
{
beginGLProcAddressTable();
}
@@ -79,7 +81,7 @@ public class GLEmitter extends JavaEmitter
public void endFunctions() throws Exception
{
- if (((GLConfiguration)getConfig()).emitProcAddressTable())
+ if (getGLConfig().emitProcAddressTable())
{
endGLProcAddressTable();
}
@@ -118,7 +120,7 @@ public class GLEmitter extends JavaEmitter
// 9 is default # expanded bindings for void*
ArrayList modifiedEmitters = new ArrayList(9);
- if (((GLConfiguration)getConfig()).emitProcAddressTable())
+ if (getGLConfig().emitProcAddressTable())
{
// emit an entry in the GL proc address table for this method.
emitGLProcAddressTableEntryForSymbol(sym);
@@ -185,7 +187,7 @@ public class GLEmitter extends JavaEmitter
return null;
return baseJavaEmitter;
}
- return new JavaGLPAWrapperEmitter(baseJavaEmitter);
+ return new JavaGLPAWrapperEmitter(baseJavaEmitter, getGLConfig().getProcAddressTableExpr());
}
private CMethodBindingEmitter generateModifiedEmitter(CMethodBindingEmitter baseCEmitter)
@@ -205,11 +207,17 @@ public class GLEmitter extends JavaEmitter
{
String symName = sym.getName();
+ GLConfiguration config = getGLConfig();
+
// We should only wrap the GL symbol if its function pointer typedef has
// been defined (most likely in glext.h).
String funcPointerTypedefName = getGLFunctionPointerTypedefName(sym);
boolean shouldWrap = typedefDictionary.containsKey(funcPointerTypedefName);
//System.err.println(funcPointerTypedefName + " defined: " + shouldWrap);
+
+ if (config.skipProcAddressGen(symName)) {
+ shouldWrap = false;
+ }
if (!shouldWrap)
{
@@ -221,26 +229,27 @@ public class GLEmitter extends JavaEmitter
private void beginGLProcAddressTable() throws Exception
{
- String implPackageName = getImplPackageName();
+ tableClassPackage = getGLConfig().tableClassPackage();
+ tableClassName = getGLConfig().tableClassName();
+
+ // Table defaults to going into the impl directory unless otherwise overridden
+ String implPackageName = tableClassPackage;
+ if (implPackageName == null) {
+ implPackageName = getImplPackageName();
+ }
String jImplRoot =
getJavaOutputDir() + File.separator +
CodeGenUtils.packageAsPath(implPackageName);
- // HACK: until we have a way to make the impl dir different from the
- // WindowsGLImpl dir and the interface dir
- //tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
- File tmpFile = new File(jImplRoot);
- tmpFile = tmpFile.getParentFile();
- tmpFile = new File(tmpFile, tableClassName + ".java");
- tableWriter = openFile(tmpFile.getPath());
- // tableWriter = openFile(jImplRoot + File.separator + ".." + File.separator + tableClassName + ".java");
+ tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
CodeGenUtils.emitAutogeneratedWarning(tableWriter, this);
- // HACK: until we have a way to make the impl dir different from the
- // WindowsGLImpl dir and the interface dir
- //tableWriter.println("package " + implPackageName + ";");
- tableWriter.println("package " + getJavaPackageName() + ".impl;");
+ tableWriter.println("package " + implPackageName + ";");
+ tableWriter.println();
+ for (Iterator iter = getConfig().imports().iterator(); iter.hasNext(); ) {
+ tableWriter.println("import " + ((String) iter.next()) + ";");
+ }
tableWriter.println();
tableWriter.println("/**");
tableWriter.println(" * This table is a cache of the native pointers to OpenGL extension");
@@ -260,9 +269,6 @@ public class GLEmitter extends JavaEmitter
private void endGLProcAddressTable() throws Exception
{
PrintWriter w = tableWriter;
- w.print(" protected static long __PROCADDRESSINDEX__LASTINDEX = ");
- w.print(numProcAddressEntries-1);
- w.println(';');
w.println();
w.println(" /**");
@@ -301,30 +307,69 @@ public class GLEmitter extends JavaEmitter
private void emitGLProcAddressTableEntryForSymbol(FunctionSymbol cFunc)
{
- tableWriter.print(" public static long ");
+ tableWriter.print(" public long ");
tableWriter.print(PROCADDRESS_VAR_PREFIX);
tableWriter.print(cFunc.getName());
tableWriter.println(";");
++numProcAddressEntries;
}
+ private GLConfiguration getGLConfig() {
+ return (GLConfiguration) getConfig();
+ }
+
protected static class GLConfiguration extends JavaConfiguration
{
private boolean emitProcAddressTable = false;
-
+ private String tableClassPackage;
+ private String tableClassName = "ProcAddressTable";
+ private Set/*<String>*/ skipProcAddressGen = new HashSet();
+ private String getProcAddressTableExpr = "context.getGLProcAddressTable()";
+
protected void dispatch(String cmd, StringTokenizer tok, File file, String filename, int lineNo) throws IOException {
if (cmd.equalsIgnoreCase("EmitProcAddressTable"))
{
emitProcAddressTable =
readBoolean("EmitProcAddressTable", tok, filename, lineNo).booleanValue();
}
+ else if (cmd.equalsIgnoreCase("ProcAddressTablePackage"))
+ {
+ tableClassPackage = readString("ProcAddressTablePackage", tok, filename, lineNo);
+ }
+ else if (cmd.equalsIgnoreCase("ProcAddressTableClassName"))
+ {
+ tableClassName = readString("ProcAddressTableClassName", tok, filename, lineNo);
+ }
+ else if (cmd.equalsIgnoreCase("SkipProcAddressGen"))
+ {
+ String sym = readString("SkipProcAddressGen", tok, filename, lineNo);
+ skipProcAddressGen.add(sym);
+ }
+ else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr"))
+ {
+ getProcAddressTableExpr = readGetProcAddressTableExpr(tok, filename, lineNo);
+ }
else
{
super.dispatch(cmd,tok,file,filename,lineNo);
}
}
- public boolean emitProcAddressTable() { return emitProcAddressTable; }
+ protected String readGetProcAddressTableExpr(StringTokenizer tok, String filename, int lineNo) {
+ try {
+ String restOfLine = tok.nextToken("\n\r\f");
+ return restOfLine.trim();
+ } catch (NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"GetProcAddressTableExpr\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
+
+ public boolean emitProcAddressTable() { return emitProcAddressTable; }
+ public String tableClassPackage() { return tableClassPackage; }
+ public String tableClassName() { return tableClassName; }
+ public boolean skipProcAddressGen (String name) { return skipProcAddressGen.contains(name); }
+ public String getProcAddressTableExpr() { return getProcAddressTableExpr; }
} // end class GLConfiguration
}
diff --git a/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java b/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java
index e0a098f2a..c3b17f6cb 100644
--- a/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java
+++ b/src/net/java/games/gluegen/opengl/JavaGLPAWrapperEmitter.java
@@ -50,10 +50,12 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter
new WrappedMethodCommentEmitter();
private JavaMethodBindingEmitter emitterBeingWrapped;
+ private String getProcAddressTableExpr;
- public JavaGLPAWrapperEmitter(JavaMethodBindingEmitter methodToWrap)
+ public JavaGLPAWrapperEmitter(JavaMethodBindingEmitter methodToWrap, String getProcAddressTableExpr)
{
super(methodToWrap.getBinding(), methodToWrap.getDefaultOutput(), methodToWrap.getRuntimeExceptionType());
+ this.getProcAddressTableExpr = getProcAddressTableExpr;
if (methodToWrap.getBinding().hasContainingType())
{
@@ -119,6 +121,9 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter
// Now make our binding use the original access of the wrapped method
this.addModifier(origAccess);
+ if (emitterBeingWrapped.hasModifier(STATIC)) {
+ this.addModifier(STATIC);
+ }
}
protected boolean needsBody() {
@@ -152,9 +157,7 @@ public class JavaGLPAWrapperEmitter extends JavaMethodBindingImplEmitter
String procAddressVariable =
GLEmitter.PROCADDRESS_VAR_PREFIX + wrappedBinding.getName();
- writer.print(" final long addr = context.getGLProcAddressTable().");
- writer.print(procAddressVariable);
- writer.println(';');
+ writer.println(" final long addr = " + getProcAddressTableExpr + "." + procAddressVariable + ";");
writer.println(" if (addr == 0) {");
writer.println(" throw new GLException(\"Method \\\"" + binding.getName() + "\\\" not available\");");
writer.println(" }");
diff --git a/src/net/java/games/gluegen/runtime/ProcAddressHelper.java b/src/net/java/games/gluegen/runtime/ProcAddressHelper.java
new file mode 100644
index 000000000..fec0eb366
--- /dev/null
+++ b/src/net/java/games/gluegen/runtime/ProcAddressHelper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution 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 Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package net.java.games.gluegen.runtime;
+
+/** Contains constants used in glue code generation. */
+
+public class ProcAddressHelper {
+ public static final String PROCADDRESS_VAR_PREFIX = "_addressof_";
+}