aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/net/java/games/gluegen/CMethodBindingEmitter.java173
-rw-r--r--src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java32
-rw-r--r--src/net/java/games/gluegen/pcpp/PCPP.java55
3 files changed, 160 insertions, 100 deletions
diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java
index 27df36cea..e72c0ab77 100644
--- a/src/net/java/games/gluegen/CMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java
@@ -349,10 +349,12 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.println(" {");
emitBodyVariableDeclarations(writer);
emitBodyUserVariableDeclarations(writer);
- emitBodyVariablePreCallSetup(writer);
+ emitBodyVariablePreCallSetup(writer, false);
+ emitBodyVariablePreCallSetup(writer, true);
emitBodyCallCFunction(writer);
emitBodyUserVariableAssignments(writer);
- emitBodyVariablePostCallCleanup(writer);
+ emitBodyVariablePostCallCleanup(writer, true);
+ emitBodyVariablePostCallCleanup(writer, false);
emitBodyReturnResult(writer);
writer.println("}");
writer.println();
@@ -365,7 +367,8 @@ public class CMethodBindingEmitter extends FunctionEmitter
emitPointerDeclaration(writer,
binding.getContainingType(),
binding.getContainingCType(),
- CMethodBindingEmitter.cThisArgumentName());
+ CMethodBindingEmitter.cThisArgumentName(),
+ null);
}
boolean emittedDataCopyTemps = false;
@@ -382,13 +385,14 @@ public class CMethodBindingEmitter extends FunctionEmitter
emitPointerDeclaration(writer,
binding.getJavaArgumentType(i),
binding.getCArgumentType(i),
- convName);
+ convName,
+ binding.getArgumentName(i));
if (needsDataCopy && !emittedDataCopyTemps) {
// emit loop counter and array length variables used during data
// copy
writer.println(" jobject _tmpObj;");
writer.println(" int _copyIndex;");
- writer.println(" jsize _arrayLen"+convName+";");
+ writer.println(" jsize _tmpArrayLen;");
emittedDataCopyTemps = true;
}
} else if (type.isString()) {
@@ -461,7 +465,8 @@ public class CMethodBindingEmitter extends FunctionEmitter
* emitBodyVariableDeclarations(), PRIOR TO calling the actual C
* function.
*/
- protected void emitBodyVariablePreCallSetup(PrintWriter writer)
+ protected void emitBodyVariablePreCallSetup(PrintWriter writer,
+ boolean emittingPrimitiveArrayCritical)
{
// Convert all Buffers to pointers first so we don't have to
// call ReleasePrimitiveArrayCritical for any arrays if any
@@ -496,6 +501,13 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
if (javaArgType.isArray()) {
+ boolean needsDataCopy = javaArgTypeNeedsDataCopy(javaArgType);
+ Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType();
+
+ if ((!needsDataCopy && !emittingPrimitiveArrayCritical) ||
+ (needsDataCopy && emittingPrimitiveArrayCritical)) {
+ continue;
+ }
if (EMIT_NULL_CHECKS) {
writer.print(" if (");
@@ -503,34 +515,31 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.println(" != NULL) {");
}
- writer.print(" ");
- String convName = pointerConversionArgumentName(i);
- writer.print(convName);
- writer.print(" = (");
Type cArgType = binding.getCArgumentType(i);
String cArgTypeName = cArgType.getName();
- if (javaArgType.isArray() &&
- javaArgType.getJavaClass().getComponentType() == java.lang.String.class) {
- // java-side type is String[]
- cArgTypeName = "jstring *";
- }
- writer.print(cArgTypeName);
- writer.print(") (*env)->GetPrimitiveArrayCritical(env, ");
- writer.print(binding.getArgumentName(i));
- writer.println(", NULL);");
-
- // Handle the case where the array elements are of a type that needs a
- // data copy operation to convert from the java memory model to the C
- // memory model (e.g., int[][], String[], etc)
- //
- // FIXME: should factor out this whole block of code into a separate
- // method for clarity and maintenance purposes
- Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType();
- boolean needsDataCopy =
- subArrayElementJavaType.isArray() ||
- subArrayElementJavaType == java.lang.String.class;
- if (needsDataCopy)
- {
+
+ String convName = pointerConversionArgumentName(i);
+
+ if (!needsDataCopy) {
+ writer.print(" ");
+ writer.print(convName);
+ writer.print(" = (");
+ if (javaArgType.isArray() &&
+ javaArgType.getJavaClass().getComponentType() == java.lang.String.class) {
+ // java-side type is String[]
+ cArgTypeName = "jstring *";
+ }
+ writer.print(cArgTypeName);
+ writer.print(") (*env)->GetPrimitiveArrayCritical(env, ");
+ writer.print(binding.getArgumentName(i));
+ writer.println(", NULL);");
+ } else {
+ // Handle the case where the array elements are of a type that needs a
+ // data copy operation to convert from the java memory model to the C
+ // memory model (e.g., int[][], String[], etc)
+ //
+ // FIXME: should factor out this whole block of code into a separate
+ // method for clarity and maintenance purposes
if (cArgType.toString().indexOf("const") == -1) {
// FIXME: if the arg type is non-const, the sematics might be that
// the function modifies the argument -- we don't yet support
@@ -546,11 +555,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
writer.println();
- writer.println(" /* Copy contents of " + convName +
+ writer.println(" /* Copy contents of " + binding.getArgumentName(i) +
" into " + convName + "_copy */");
// get length of array being copied
- String arrayLenName = "_arrayLen"+convName;
+ String arrayLenName = "_tmpArrayLen";
writer.print(" ");
writer.print(arrayLenName);
writer.print(" = (*env)->GetArrayLength(env, ");
@@ -628,6 +637,10 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
} else if (javaArgType.isString()) {
+ if (emittingPrimitiveArrayCritical) {
+ continue;
+ }
+
if (EMIT_NULL_CHECKS) {
writer.print(" if (");
writer.print(binding.getArgumentName(i));
@@ -645,7 +658,6 @@ public class CMethodBindingEmitter extends FunctionEmitter
// FIXME
throw new RuntimeException("Outgoing arrays of StructAccessors not yet implemented");
-
}
}
}
@@ -655,7 +667,8 @@ public class CMethodBindingEmitter extends FunctionEmitter
* Code to clean up any variables that were declared in
* emitBodyVariableDeclarations(), AFTER calling the actual C function.
*/
- protected void emitBodyVariablePostCallCleanup(PrintWriter writer)
+ protected void emitBodyVariablePostCallCleanup(PrintWriter writer,
+ boolean emittingPrimitiveArrayCritical)
{
// Release primitive arrays and temporary UTF8 strings if necessary
for (int i = 0; i < binding.getNumArguments(); i++) {
@@ -664,27 +677,36 @@ public class CMethodBindingEmitter extends FunctionEmitter
continue;
}
if (javaArgType.isArray()) {
- String convName = pointerConversionArgumentName(i);
+ boolean needsDataCopy = javaArgTypeNeedsDataCopy(javaArgType);
+ Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType();
+
+ if ((!needsDataCopy && !emittingPrimitiveArrayCritical) ||
+ (needsDataCopy && emittingPrimitiveArrayCritical)) {
+ continue;
+ }
- // Release array
if (EMIT_NULL_CHECKS) {
writer.print(" if (");
writer.print(binding.getArgumentName(i));
writer.println(" != NULL) {");
}
- // clean up the case where the array elements are of a type that needed
- // a data copy operation to convert from the java memory model to the
- // C memory model (e.g., int[][], String[], etc)
- //
- // FIXME: should factor out this whole block of code into a separate
- // method for clarity and maintenance purposes
- Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType();
- boolean needsDataCopy =
- subArrayElementJavaType.isArray() ||
- subArrayElementJavaType == java.lang.String.class;
- if (needsDataCopy)
- {
+ String convName = pointerConversionArgumentName(i);
+
+ if (!needsDataCopy) {
+ // Release array
+ writer.print(" (*env)->ReleasePrimitiveArrayCritical(env, ");
+ writer.print(binding.getArgumentName(i));
+ writer.print(", ");
+ writer.print(convName);
+ writer.println(", JNI_ABORT);");
+ } else {
+ // clean up the case where the array elements are of a type that needed
+ // a data copy operation to convert from the java memory model to the
+ // C memory model (e.g., int[][], String[], etc)
+ //
+ // FIXME: should factor out this whole block of code into a separate
+ // method for clarity and maintenance purposes
Type cArgType = binding.getCArgumentType(i);
String cArgTypeName = cArgType.getName();
@@ -699,7 +721,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
writer.println(" /* Clean up " + convName + "_copy */");
- String arrayLenName = "_arrayLen" + convName;
+ String arrayLenName = "_tmpArrayLen";
// free each element
PointerType cArgPtrType = cArgType.asPointer();
@@ -748,17 +770,16 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.println();
} // end of cleaning up copied data
- writer.print(" (*env)->ReleasePrimitiveArrayCritical(env, ");
- writer.print(binding.getArgumentName(i));
- writer.print(", ");
- writer.print(convName);
- writer.println(", JNI_ABORT);");
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
} else if (javaArgType.isString()) {
+ if (emittingPrimitiveArrayCritical) {
+ continue;
+ }
+
if (EMIT_NULL_CHECKS) {
writer.print(" if (");
writer.print(binding.getArgumentName(i));
@@ -828,6 +849,9 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
if (javaArgType.isArray() || javaArgType.isNIOBuffer()) {
writer.print(pointerConversionArgumentName(i));
+ if (javaArgTypeNeedsDataCopy(javaArgType)) {
+ writer.print("_copy");
+ }
} else {
if (javaArgType.isString()) { writer.print("_UTF8"); }
writer.print(binding.getArgumentName(i));
@@ -1036,7 +1060,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(" if (");
writer.print(varName);
writer.println(" == NULL) {");
- writer.println(" (*env)->ThrowNew(env, (*env)->FindClass(env, \"java/lang/OutOfMemoryException\"),");
+ writer.println(" (*env)->ThrowNew(env, (*env)->FindClass(env, \"java/lang/OutOfMemoryError\"),");
writer.print(" \"" + errorMessage);
writer.print(" in native dispatcher for \\\"");
writer.print(binding.getName());
@@ -1097,7 +1121,8 @@ public class CMethodBindingEmitter extends FunctionEmitter
private boolean emitPointerDeclaration(PrintWriter writer,
JavaType javaType,
Type cType,
- String cVariableName) {
+ String cVariableName,
+ String javaArgumentName) {
String ptrTypeString = null;
boolean needsDataCopy = false;
@@ -1110,6 +1135,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
ptrTypeString = cType.getName();
}
else if (javaType.isArray()) {
+ needsDataCopy = javaArgTypeNeedsDataCopy(javaType);
// It's an array; get the type of the elements in the array
Class elementType = javaType.getJavaClass().getComponentType();
if (elementType.isPrimitive())
@@ -1119,12 +1145,9 @@ public class CMethodBindingEmitter extends FunctionEmitter
else if (elementType == java.lang.String.class)
{
ptrTypeString = "jstring *";
- needsDataCopy = true;
}
else if (elementType.isArray())
{
- needsDataCopy = true;
-
Class subElementType = elementType.getComponentType();
if (subElementType.isPrimitive())
{
@@ -1155,14 +1178,16 @@ public class CMethodBindingEmitter extends FunctionEmitter
ptrTypeString = cType.getName();
}
- // declare the pointer variable
- writer.print(" ");
- writer.print(ptrTypeString);
- writer.print(" ");
- writer.print(cVariableName);
- writer.println(" = NULL;");
-
- if (needsDataCopy)
+ if (!needsDataCopy)
+ {
+ // declare the pointer variable
+ writer.print(" ");
+ writer.print(ptrTypeString);
+ writer.print(" ");
+ writer.print(cVariableName);
+ writer.println(" = NULL;");
+ }
+ else
{
// Declare a variable to hold a copy of the argument data in which the
// incoming data has been properly laid out in memory to match the C
@@ -1178,7 +1203,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(" ");
writer.print(cVariableName);
writer.print("_copy = NULL; /* copy of data in ");
- writer.print(cVariableName);
+ writer.print(javaArgumentName);
writer.println(", laid out according to C memory model */");
}
@@ -1239,5 +1264,13 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
}
+ protected boolean javaArgTypeNeedsDataCopy(JavaType javaArgType) {
+ if (javaArgType.isArray()) {
+ Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType();
+ return (subArrayElementJavaType.isArray() ||
+ subArrayElementJavaType == java.lang.String.class);
+ }
+ return false;
+ }
}
diff --git a/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java b/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
index 2a1559e52..bb80190d3 100644
--- a/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
+++ b/src/net/java/games/gluegen/opengl/CGLPAWrapperEmitter.java
@@ -113,24 +113,27 @@ public class CGLPAWrapperEmitter extends CMethodBindingEmitter
super.emitBodyVariableDeclarations(writer);
}
- protected void emitBodyVariablePreCallSetup(PrintWriter writer)
+ protected void emitBodyVariablePreCallSetup(PrintWriter writer,
+ boolean emittingPrimitiveArrayCritical)
{
- super.emitBodyVariablePreCallSetup(writer);
+ super.emitBodyVariablePreCallSetup(writer, emittingPrimitiveArrayCritical);
- // set the function pointer to the value of the passed-in glProcAddress
- FunctionSymbol cSym = getBinding().getCSymbol();
- String funcPointerTypedefName =
- GLEmitter.getGLFunctionPointerTypedefName(cSym);
+ if (!emittingPrimitiveArrayCritical) {
+ // set the function pointer to the value of the passed-in glProcAddress
+ FunctionSymbol cSym = getBinding().getCSymbol();
+ String funcPointerTypedefName =
+ GLEmitter.getGLFunctionPointerTypedefName(cSym);
- String ptrVarName = "ptr_" + cSym.getName();
+ String ptrVarName = "ptr_" + cSym.getName();
- writer.print(" ");
- writer.print(ptrVarName);
- writer.print(" = (");
- writer.print(funcPointerTypedefName);
- writer.println(") (intptr_t) glProcAddress;");
+ writer.print(" ");
+ writer.print(ptrVarName);
+ writer.print(" = (");
+ writer.print(funcPointerTypedefName);
+ writer.println(") (intptr_t) glProcAddress;");
- writer.println(" assert(" + ptrVarName + " != NULL);");
+ writer.println(" assert(" + ptrVarName + " != NULL);");
+ }
}
// FIXME: refactor this and the superclass version so we don't have to copy
@@ -192,6 +195,9 @@ public class CGLPAWrapperEmitter extends CMethodBindingEmitter
}
if (javaType.isArray() || javaType.isNIOBuffer()) {
writer.print(pointerConversionArgumentName(i));
+ if (javaArgTypeNeedsDataCopy(javaType)) {
+ writer.print("_copy");
+ }
} else {
if (javaType.isString()) { writer.print("_UTF8"); }
writer.print(binding.getArgumentName(i));
diff --git a/src/net/java/games/gluegen/pcpp/PCPP.java b/src/net/java/games/gluegen/pcpp/PCPP.java
index 4bddc976f..585d0d9fa 100644
--- a/src/net/java/games/gluegen/pcpp/PCPP.java
+++ b/src/net/java/games/gluegen/pcpp/PCPP.java
@@ -143,7 +143,8 @@ public class PCPP {
to constants. Macros and multi-line defines (which typically
contain either macro definitions or expressions) are currently
not handled. */
- private Map/*<String, String>*/ defineMap = new HashMap();
+ private Map/*<String, String>*/ defineMap = new HashMap();
+ private Set/*<String>*/ nonConstantDefines = new HashSet();
/** List containing the #include paths as Strings */
private List/*<String>*/ includePaths;
@@ -364,9 +365,9 @@ public class PCPP {
} else {
// System.err.println("UNDEFINED: '" + name + "' (line " + lineNumber() + " file " + filename() + ")");
}
+ nonConstantDefines.remove(name);
}
else System.err.println("FAILED TO UNDEFINE: '" + name + "' (line " + lineNumber() + " file " + filename() + ")");
-
}
private void handleDefine() throws IOException {
@@ -414,7 +415,7 @@ public class PCPP {
} else {
// Value is a symbolic constant like "#define FOO BAR".
// Try to look up the symbol's value
- String newValue = (String) defineMap.get(value);
+ String newValue = resolveDefine(value, true);
if (newValue != null) {
// Set the value to the value of the symbol.
//
@@ -427,30 +428,32 @@ public class PCPP {
{
// Still perform textual replacement
defineMap.put(name, value);
+ nonConstantDefines.add(name);
emitDefine = false;
}
}
}
else
{
- // can't handle definitions that aren't constants or empty
+ // Non-constant define; try to do reasonable textual substitution anyway
+ // (FIXME: should identify some of these, like (-1), as constants)
emitDefine = false;
- StringBuffer buf = new StringBuffer("#define ");
- buf.append(name);
- for (int i = 0; i < sz; ++i) {
- buf.append(" ");
- buf.append(values.get(i));
+ StringBuffer val = new StringBuffer();
+ for (int i = 0; i < sz; i++) {
+ if (i != 0) {
+ val.append(" ");
+ }
+ val.append(resolveDefine((String) values.get(i), false));
}
- System.err.println("WARNING: Ignoring \"" + buf.toString() +
- "\" at \"" + filename() + "\" line " + lineNumber() +
- ": Unable to handle definition to non-constant");
if (defineMap.get(name) != null) {
- // This is probably something the user should investigate.
+ // This is probably something the user should investigate.
throw new RuntimeException("Cannot redefine symbol \"" + name +
" from \"" + defineMap.get(name) + "\" to non-constant " +
- " definition \"" + buf.toString() + "\"");
+ " definition \"" + val.toString() + "\"");
}
- }
+ defineMap.put(name, val.toString());
+ nonConstantDefines.add(name);
+ }
if (emitDefine)
{
@@ -500,6 +503,24 @@ public class PCPP {
return true;
}
+ private String resolveDefine(String word, boolean returnNullIfNotFound) {
+ String lastWord = (String) defineMap.get(word);
+ if (lastWord == null) {
+ if (returnNullIfNotFound) {
+ return null;
+ }
+ return word;
+ }
+ String nextWord = null;
+ do {
+ nextWord = (String) defineMap.get(lastWord);
+ if (nextWord != null) {
+ lastWord = nextWord;
+ }
+ } while (nextWord != null);
+ return lastWord;
+ }
+
////////////////////////////////////////////////
// Handling of #if/#ifdef/ifndef/endif directives //
////////////////////////////////////////////////
@@ -628,8 +649,8 @@ public class PCPP {
// See if the statement is "true"; i.e., a non-zero expression
if (symbolValue != null) {
- // The statement is true if the symbol is defined.
- return true;
+ // The statement is true if the symbol is defined and is a constant expression
+ return (!nonConstantDefines.contains(word));
} else {
// The statement is true if the symbol evaluates to a non-zero value
//