summaryrefslogtreecommitdiffstats
path: root/src/net/java/games/gluegen
diff options
context:
space:
mode:
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_";
+}