summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/java/games/gluegen/ArrayTypes.java78
-rw-r--r--src/net/java/games/gluegen/CMethodBindingEmitter.java163
-rw-r--r--src/net/java/games/gluegen/JavaEmitter.java74
-rw-r--r--src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java14
-rw-r--r--src/net/java/games/gluegen/JavaType.java9
-rw-r--r--src/net/java/games/gluegen/MethodBinding.java3
-rw-r--r--src/net/java/games/gluegen/cgram/types/Type.java14
7 files changed, 230 insertions, 125 deletions
diff --git a/src/net/java/games/gluegen/ArrayTypes.java b/src/net/java/games/gluegen/ArrayTypes.java
index 86867866a..908a3d765 100644
--- a/src/net/java/games/gluegen/ArrayTypes.java
+++ b/src/net/java/games/gluegen/ArrayTypes.java
@@ -39,14 +39,14 @@
package net.java.games.gluegen;
+import java.nio.*;
+
/**
* Convenience class containing the Class objects corresponding to arrays of
* various types (e.g., {@link #booleanArrayClass} is the Class of Java type
* "boolean[]").
*/
public class ArrayTypes {
- /** Class for Java type string[] */
- public static final Class stringArrayClass;
/** Class for Java type boolean[] */
public static final Class booleanArrayClass;
/** Class for Java type byte[] */
@@ -63,28 +63,47 @@ public class ArrayTypes {
public static final Class floatArrayClass;
/** Class for Java type double[] */
public static final Class doubleArrayClass;
+ /** Class for Java type String[] */
+ public static final Class stringArrayClass;
- /** Class for Java type string[][] */
- public static final Class stringArrayArrayClass;
- /** Class for Java type boolean[][] */
- public static final Class booleanArrayArrayClass;
- /** Class for Java type byte[][] */
- public static final Class byteArrayArrayClass;
- /** Class for Java type char[][] */
- public static final Class charArrayArrayClass;
- /** Class for Java type short[][] */
- public static final Class shortArrayArrayClass;
- /** Class for Java type int[][] */
- public static final Class intArrayArrayClass;
- /** Class for Java type long[][] */
- public static final Class longArrayArrayClass;
- /** Class for Java type float[][] */
- public static final Class floatArrayArrayClass;
- /** Class for Java type double[][] */
- public static final Class doubleArrayArrayClass;
+ // Classes for two-dimensional arrays.
+ //
+ // GlueGen converts C types like int** into Java arrays of direct
+ // buffers of the appropriate type (like IntBuffer[]). If the tool
+ // supported conversions like byte[][] -> char**, it would
+ // effectively be necessary to copy all of the data from the Java
+ // heap to the C heap during each call. The reason for this is that
+ // if we wanted to use GetPrimitiveArrayCritical to lock down the
+ // storage for each individual array element, we would need to fetch
+ // each element of the two-dimensional Java array into temporary
+ // storage before making the first GetPrimitiveArrayCritical call,
+ // since one can not call GetObjectArrayElement inside a Get /
+ // ReleasePrimitiveArrayCritical pair. This means that we would need
+ // two top-level pieces of temporary storage for the two-dimensional
+ // array as well as two loops to set up the contents, which would be
+ // too complicated.
+ //
+ // The one concession we make is converting String[] -> char**. The
+ // JVM takes care of the C heap allocation for GetStringUTFChars and
+ // ReleaseStringUTFChars, and this conversion is important for
+ // certain OpenGL operations.
+
+ /** Class for Java type Buffer[] */
+ public static final Class bufferArrayClass;
+ /** Class for Java type ByteBuffer[] */
+ public static final Class byteBufferArrayClass;
+ /** Class for Java type ShortBuffer[] */
+ public static final Class shortBufferArrayClass;
+ /** Class for Java type IntBuffer[] */
+ public static final Class intBufferArrayClass;
+ /** Class for Java type LongBuffer[] */
+ public static final Class longBufferArrayClass;
+ /** Class for Java type FloatBuffer[] */
+ public static final Class floatBufferArrayClass;
+ /** Class for Java type DoubleBuffer[] */
+ public static final Class doubleBufferArrayClass;
static {
- stringArrayClass = new String [0].getClass();
booleanArrayClass = new boolean[0].getClass();
byteArrayClass = new byte [0].getClass();
charArrayClass = new char [0].getClass();
@@ -93,15 +112,14 @@ public class ArrayTypes {
longArrayClass = new long [0].getClass();
floatArrayClass = new float [0].getClass();
doubleArrayClass = new double [0].getClass();
+ stringArrayClass = new String [0].getClass();
- stringArrayArrayClass = new String [0][0].getClass();
- booleanArrayArrayClass = new boolean[0][0].getClass();
- byteArrayArrayClass = new byte [0][0].getClass();
- charArrayArrayClass = new char [0][0].getClass();
- shortArrayArrayClass = new short [0][0].getClass();
- intArrayArrayClass = new int [0][0].getClass();
- longArrayArrayClass = new long [0][0].getClass();
- floatArrayArrayClass = new float [0][0].getClass();
- doubleArrayArrayClass = new double [0][0].getClass();
+ bufferArrayClass = new Buffer [0].getClass();
+ byteBufferArrayClass = new ByteBuffer [0].getClass();
+ shortBufferArrayClass = new ShortBuffer [0].getClass();
+ intBufferArrayClass = new IntBuffer [0].getClass();
+ longBufferArrayClass = new LongBuffer [0].getClass();
+ floatBufferArrayClass = new FloatBuffer [0].getClass();
+ doubleBufferArrayClass = new DoubleBuffer[0].getClass();
}
}
diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java
index e0abf86a6..b9cc0091e 100644
--- a/src/net/java/games/gluegen/CMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java
@@ -576,7 +576,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
throw new RuntimeException(
"Could not copy data for type \"" + cArgType +
"\"; copying only supported for types of the form " +
- "ptr-to-ptr-to-primitive.");
+ "ptr-to-ptr-to-type.");
}
PointerType cArgPtrType = cArgType.asPointer();
if (cArgPtrType == null) {
@@ -611,6 +611,13 @@ public class CMethodBindingEmitter extends FunctionEmitter
"(jstring) _tmpObj",
"(const char*)"+convName+"_copy[_copyIndex]");
}
+ else if (isNIOBufferClass(subArrayElementJavaType))
+ {
+ emitGetDirectBufferAddress(writer,
+ "_tmpObj",
+ cArgElementType.getName(),
+ convName + "_copy[_copyIndex]");
+ }
else
{
// Question: do we always need to copy the sub-arrays, or just
@@ -625,7 +632,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
cArgElementType.getTargetType().getName(), // assumes cArgPtrType is ptr-to-ptr-to-primitive !!
"(*env)->GetArrayLength(env, _tmpObj)",
"Could not allocate buffer during copying of data in argument \\\""+binding.getArgumentName(i)+"\\\"");
- // FIXME: copy the data (use Get<type>ArrayRegion() calls)
+ // FIXME: copy the data (use matched Get/ReleasePrimitiveArrayCritical() calls)
if (true) throw new RuntimeException(
"Cannot yet handle type \"" + cArgType.getName() +
"\"; need to add support for copying ptr-to-ptr-to-primitiveType subarrays");
@@ -727,63 +734,58 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.println(" /* Clean up " + convName + "_copy */");
- // Re-fetch length of array that was copied
- String arrayLenName = "_tmpArrayLen";
- writer.print(" ");
- writer.print(arrayLenName);
- writer.print(" = (*env)->GetArrayLength(env, ");
- writer.print(binding.getArgumentName(i));
- writer.println(");");
-
- // free each element
- PointerType cArgPtrType = cArgType.asPointer();
- if (cArgPtrType == null) {
- throw new RuntimeException(
- "Could not copy data for type \"" + cArgType +
- "\"; currently only pointer types supported.");
- }
- PointerType cArgElementType = cArgPtrType.getTargetType().asPointer();
+ // Only need to perform cleanup for individual array
+ // elements if they are not direct buffers
+ if (!isNIOBufferClass(subArrayElementJavaType)) {
+ // Re-fetch length of array that was copied
+ String arrayLenName = "_tmpArrayLen";
+ writer.print(" ");
+ writer.print(arrayLenName);
+ writer.print(" = (*env)->GetArrayLength(env, ");
+ writer.print(binding.getArgumentName(i));
+ writer.println(");");
+
+ // free each element
+ PointerType cArgPtrType = cArgType.asPointer();
+ if (cArgPtrType == null) {
+ throw new RuntimeException(
+ "Could not copy data for type \"" + cArgType +
+ "\"; currently only pointer types supported.");
+ }
+ PointerType cArgElementType = cArgPtrType.getTargetType().asPointer();
- // process each element in the array
- writer.println(" for (_copyIndex = 0; _copyIndex < " + arrayLenName +"; ++_copyIndex) {");
-
- // get each array element
- writer.println(" /* free each element of " +convName +"_copy */");
- String subArrayElementJNITypeString = jniType(subArrayElementJavaType);
- writer.print(" _tmpObj = (");
- writer.print(subArrayElementJNITypeString);
- writer.print(") (*env)->GetObjectArrayElement(env, ");
- writer.print(binding.getArgumentName(i));
- writer.println(", _copyIndex);");
-
- if (subArrayElementJNITypeString == "jstring")
- {
- writer.print(" (*env)->ReleaseStringUTFChars(env, ");
- writer.print("(jstring) _tmpObj");
- writer.print(", ");
- writer.print(convName+"_copy[_copyIndex]");
- writer.println(");");
- }
- else
- {
- // FIXME: free up stuff here
- if (true) throw new RuntimeException(
- "Cannot yet handle type \"" + cArgType.getName() +
- "\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays");
+ // process each element in the array
+ writer.println(" for (_copyIndex = 0; _copyIndex < " + arrayLenName +"; ++_copyIndex) {");
+
+ // get each array element
+ writer.println(" /* free each element of " +convName +"_copy */");
+ String subArrayElementJNITypeString = jniType(subArrayElementJavaType);
+ writer.print(" _tmpObj = (");
+ writer.print(subArrayElementJNITypeString);
+ writer.print(") (*env)->GetObjectArrayElement(env, ");
+ writer.print(binding.getArgumentName(i));
+ writer.println(", _copyIndex);");
+
+ if (subArrayElementJNITypeString == "jstring") {
+ writer.print(" (*env)->ReleaseStringUTFChars(env, ");
+ writer.print("(jstring) _tmpObj");
+ writer.print(", ");
+ writer.print(convName+"_copy[_copyIndex]");
+ writer.println(");");
+ } else {
+ if (true) throw new RuntimeException(
+ "Cannot yet handle type \"" + cArgType.getName() +
+ "\"; need to add support for cleaning up copied ptr-to-ptr-to-primitiveType subarrays");
+ }
+ writer.println(" }");
}
- writer.println(" }");
// free the main array
writer.print(" free(");
writer.print(convName+"_copy");
writer.println(");");
-
-
- writer.println();
} // end of cleaning up copied data
-
-
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
@@ -1059,10 +1061,12 @@ public class CMethodBindingEmitter extends FunctionEmitter
return "j" + javaType.getName();
} else if (javaType == java.lang.String.class) {
return "jstring";
+ } else if (isNIOBufferClass(javaType)) {
+ return "jobject";
} else {
throw new RuntimeException(
"Could not determine JNI type for Java class \"" +
- javaType.getName() + "\"; was not String or primitive");
+ javaType.getName() + "\"; was not String, primitive or direct buffer");
}
}
@@ -1112,7 +1116,10 @@ public class CMethodBindingEmitter extends FunctionEmitter
String sourceVarName,
String receivingVarName)
{
- writer.print(" ");
+ writer.print(" if (");
+ writer.print(sourceVarName);
+ writer.println(" != NULL) {");
+ writer.print(" ");
writer.print(receivingVarName);
writer.print(" = (*env)->GetStringUTFChars(env, ");
writer.print(sourceVarName);
@@ -1124,8 +1131,39 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer, receivingVarName,
"Failed to get UTF-8 chars for argument \\\""+sourceVarName+"\\\"");
}
+ writer.println(" } else {");
+ writer.print(" ");
+ writer.print(receivingVarName);
+ writer.println(" = NULL;");
+ writer.println(" }");
}
+ private void emitGetDirectBufferAddress(PrintWriter writer,
+ String sourceVarName,
+ String receivingVarTypeString,
+ String receivingVarName) {
+ if (EMIT_NULL_CHECKS) {
+ writer.print(" if (");
+ writer.print(sourceVarName);
+ writer.println(" != NULL) {");
+ }
+ writer.print(" ");
+ writer.print(receivingVarName);
+ writer.print(" = (");
+ writer.print(receivingVarTypeString);
+ writer.print(") (*env)->GetDirectBufferAddress(env, ");
+ writer.print(sourceVarName);
+ writer.println(");");
+ if (EMIT_NULL_CHECKS) {
+ writer.println(" } else {");
+ writer.print(" ");
+ writer.print(receivingVarName);
+ writer.println(" = NULL;");
+ writer.println(" }");
+ }
+ }
+
+
// Note: if the data in the Type needs to be converted from the Java memory
// model to the C memory model prior to calling any C-side functions, then
// an extra variable named XXX_copy (where XXX is the value of the
@@ -1156,7 +1194,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
else if (elementType == java.lang.String.class)
{
- ptrTypeString = "jstring *";
+ ptrTypeString = "jstring";
}
else if (elementType.isArray())
{
@@ -1174,6 +1212,11 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
}
+ else if (isNIOBufferClass(elementType))
+ {
+ // type is an array of direct buffers of some sort
+ ptrTypeString = cType.getName();
+ }
else
{
// Type is pointer to something we can't/don't handle
@@ -1228,6 +1271,12 @@ public class CMethodBindingEmitter extends FunctionEmitter
Type cType,
String incomingArgumentName,
String cVariableName) {
+ emitGetDirectBufferAddress(writer,
+ incomingArgumentName,
+ cType.getName(),
+ cVariableName);
+
+ /*
if (EMIT_NULL_CHECKS) {
writer.print(" if (");
writer.print(incomingArgumentName);
@@ -1245,6 +1294,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
if (EMIT_NULL_CHECKS) {
writer.println(" }");
}
+ */
}
protected String pointerConversionArgumentName(int i) {
@@ -1280,9 +1330,14 @@ public class CMethodBindingEmitter extends FunctionEmitter
if (javaArgType.isArray()) {
Class subArrayElementJavaType = javaArgType.getJavaClass().getComponentType();
return (subArrayElementJavaType.isArray() ||
- subArrayElementJavaType == java.lang.String.class);
+ subArrayElementJavaType == java.lang.String.class ||
+ isNIOBufferClass(subArrayElementJavaType));
}
return false;
}
+
+ protected static boolean isNIOBufferClass(Class c) {
+ return java.nio.Buffer.class.isAssignableFrom(c);
+ }
}
diff --git a/src/net/java/games/gluegen/JavaEmitter.java b/src/net/java/games/gluegen/JavaEmitter.java
index 46d976b23..33a741364 100644
--- a/src/net/java/games/gluegen/JavaEmitter.java
+++ b/src/net/java/games/gluegen/JavaEmitter.java
@@ -752,7 +752,7 @@ public class JavaEmitter implements GlueEmitter {
} else if (t.isVoid()) {
return javaType(Void.TYPE);
} else {
- if (t.pointerDepth() > 0 || arrayDimension(t) > 0) {
+ if (t.pointerDepth() > 0 || t.arrayDimension() > 0) {
Type targetType; // target type
if (t.isPointer()) {
// t is <type>*, we need to get <type>
@@ -765,7 +765,7 @@ public class JavaEmitter implements GlueEmitter {
// Handle Types of form pointer-to-type or array-of-type, like
// char* or int[]; these are expanded out into Java primitive
// arrays, NIO buffers, or both in expandMethodBinding
- if (t.pointerDepth() == 1 || arrayDimension(t) == 1) {
+ if (t.pointerDepth() == 1 || t.arrayDimension() == 1) {
if (targetType.isVoid()) {
return JavaType.createForVoidPointer();
} else if (targetType.isInt()) {
@@ -808,7 +808,7 @@ public class JavaEmitter implements GlueEmitter {
}
// Handle Types of form pointer-to-pointer-to-type or
// array-of-arrays-of-type, like char** or int[][]
- else if (t.pointerDepth() == 2 || arrayDimension(t) == 2) {
+ else if (t.pointerDepth() == 2 || t.arrayDimension() == 2) {
// 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)
@@ -820,28 +820,38 @@ public class JavaEmitter implements GlueEmitter {
// t is<type>[][], targetType is <type>[], we need to get <type>
bottomType = targetType.asArray().getElementType();
}
- if (bottomType.isInt()) {
- switch (bottomType.getSize())
- {
- case 1: return javaType(ArrayTypes.byteArrayArrayClass);
- // FIXME: handle 2,4,8-byte int types here
- default:
- throw new RuntimeException(
- "Could not convert C type \"" + t + "\" to appropriate " +
- "Java type; Currently, the only supported depth=2 " +
- "pointer/array integer types are \"char**\" and \"char[][]\"");
+
+ if (bottomType.isPrimitive()) {
+ if (bottomType.isInt()) {
+ switch (bottomType.getSize()) {
+ case 1: return javaType(ArrayTypes.byteBufferArrayClass);
+ case 2: return javaType(ArrayTypes.shortBufferArrayClass);
+ case 4: return javaType(ArrayTypes.intBufferArrayClass);
+ case 8: return javaType(ArrayTypes.longBufferArrayClass);
+ default: throw new RuntimeException("Unknown two-dimensional integer array type of element size " +
+ bottomType.getSize() + " and name " + bottomType.getName());
+ }
+ } else if (bottomType.isFloat()) {
+ return javaType(ArrayTypes.floatBufferArrayClass);
+ } else if (bottomType.isDouble()) {
+ return javaType(ArrayTypes.doubleBufferArrayClass);
+ } else {
+ throw new RuntimeException("Unexpected primitive type " + bottomType.getName() +
+ " in two-dimensional array");
}
- } else if (targetType.isPointer() && (targetType.pointerDepth() == 1)) {
+ } else if (bottomType.isVoid()) {
+ return javaType(ArrayTypes.bufferArrayClass);
+ } else if (targetType.isPointer() && (targetType.pointerDepth() == 1) &&
+ targetType.asPointer().getTargetType().isCompound()) {
// 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 more support for " +
- "depth=2 pointer/array types with non-integral target " +
- "types [debug info: targetType=\"" + targetType + "\"]");
+ "depth=2 pointer/array types [debug info: targetType=\"" +
+ targetType + "\"]");
}
-
} else {
// can't handle this type of pointer/array argument
throw new RuntimeException(
@@ -849,7 +859,7 @@ public class JavaEmitter implements GlueEmitter {
"appropriate Java type; types with pointer/array depth " +
"greater than 2 are not yet supported [debug info: " +
"pointerDepth=" + t.pointerDepth() + " arrayDimension=" +
- arrayDimension(t) + " targetType=\"" + targetType + "\"]");
+ t.arrayDimension() + " targetType=\"" + targetType + "\"]");
}
} else {
@@ -906,14 +916,6 @@ public class JavaEmitter implements GlueEmitter {
return new PrintWriter(new BufferedWriter(new FileWriter(file)));
}
- private int arrayDimension(Type type) {
- ArrayType arrayType = type.asArray();
- if (arrayType == null) {
- return 0;
- }
- return 1 + arrayDimension(arrayType.getElementType());
- }
-
private boolean isOpaque(Type type) {
return (cfg.typeInfo(type, typedefDictionary) != null);
}
@@ -1187,7 +1189,7 @@ public class JavaEmitter implements GlueEmitter {
"Cannot apply ReturnsString configuration directive to \"" + sym +
"\". ReturnsString requires native method to have return type \"char *\"");
}
- binding.setJavaReturnType(JavaType.createForClass(java.lang.String.class));
+ binding.setJavaReturnType(javaType(java.lang.String.class));
} else {
binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), false));
}
@@ -1207,9 +1209,9 @@ public class JavaEmitter implements GlueEmitter {
//System.out.println("Forcing conversion of " + binding.getName() + " arg #" + i + " from byte[] to String ");
if (mappedType.isCVoidPointerType() ||
mappedType.isCCharPointerType() ||
- (mappedType.isArray() && mappedType.getJavaClass() == ArrayTypes.byteArrayArrayClass)) {
- // convert mapped type from void* and byte[] to String, or byte[][] to String[]
- if (mappedType.getJavaClass() == ArrayTypes.byteArrayArrayClass) {
+ (mappedType.isArray() && mappedType.getJavaClass() == ArrayTypes.byteBufferArrayClass)) {
+ // convert mapped type from void* and byte[] to String, or ByteBuffer[] to String[]
+ if (mappedType.getJavaClass() == ArrayTypes.byteBufferArrayClass) {
mappedType = javaType(ArrayTypes.stringArrayClass);
} else {
mappedType = javaType(String.class);
@@ -1330,22 +1332,22 @@ public class JavaEmitter implements GlueEmitter {
variant = mb.createCPrimitivePointerVariant(-1, JavaType.forNIOByteBufferClass());
if (! result.contains(variant)) result.add(variant);
} else if (mb.getJavaReturnType().isCCharPointerType()) {
- variant = mb.createCPrimitivePointerVariant(-1, JavaType.createForClass(ArrayTypes.byteArrayClass));
+ variant = mb.createCPrimitivePointerVariant(-1, javaType(ArrayTypes.byteArrayClass));
if (! result.contains(variant)) result.add(variant);
} else if (mb.getJavaReturnType().isCShortPointerType()) {
- variant = mb.createCPrimitivePointerVariant(-1, JavaType.createForClass(ArrayTypes.shortArrayClass));
+ variant = mb.createCPrimitivePointerVariant(-1, javaType(ArrayTypes.shortArrayClass));
if (! result.contains(variant)) result.add(variant);
} else if (mb.getJavaReturnType().isCInt32PointerType()) {
- variant = mb.createCPrimitivePointerVariant(-1, JavaType.createForClass(ArrayTypes.intArrayClass));
+ variant = mb.createCPrimitivePointerVariant(-1, javaType(ArrayTypes.intArrayClass));
if (! result.contains(variant)) result.add(variant);
} else if (mb.getJavaReturnType().isCInt64PointerType()) {
- variant = mb.createCPrimitivePointerVariant(-1, JavaType.createForClass(ArrayTypes.longArrayClass));
+ variant = mb.createCPrimitivePointerVariant(-1, javaType(ArrayTypes.longArrayClass));
if (! result.contains(variant)) result.add(variant);
} else if (mb.getJavaReturnType().isCFloatPointerType()) {
- variant = mb.createCPrimitivePointerVariant(-1, JavaType.createForClass(ArrayTypes.floatArrayClass));
+ variant = mb.createCPrimitivePointerVariant(-1, javaType(ArrayTypes.floatArrayClass));
if (! result.contains(variant)) result.add(variant);
} else if (mb.getJavaReturnType().isCDoublePointerType()) {
- variant = mb.createCPrimitivePointerVariant(-1, JavaType.createForClass(ArrayTypes.doubleArrayClass));
+ variant = mb.createCPrimitivePointerVariant(-1, javaType(ArrayTypes.doubleArrayClass));
if (! result.contains(variant)) result.add(variant);
}
shouldRemoveCurrent = true;
diff --git a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
index 78a4a6ced..2701bc2ec 100644
--- a/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
+++ b/src/net/java/games/gluegen/JavaMethodBindingImplEmitter.java
@@ -102,10 +102,22 @@ public class JavaMethodBindingImplEmitter extends JavaMethodBindingEmitter
writer.println(" throw new " + getRuntimeExceptionType() + "(\"Length of array \\\"" + binding.getArgumentName(i) +
"\\\" was less than the required " + arrayType.getLength() + "\");");
} else {
- if (binding.getJavaArgumentType(i).isNIOBuffer()) {
+ JavaType javaType = binding.getJavaArgumentType(i);
+ if (javaType.isNIOBuffer()) {
writer.println(" if (!BufferFactory.isDirect(" + binding.getArgumentName(i) + "))");
writer.println(" throw new " + getRuntimeExceptionType() + "(\"Argument \\\"" +
binding.getArgumentName(i) + "\\\" was not a direct buffer\");");
+ } else if (javaType.isNIOBufferArray()) {
+ String argName = binding.getArgumentName(i);
+ // Check direct buffer properties of all buffers within
+ writer.println(" if (" + argName + " != null) {");
+ writer.println(" for (int _ctr = 0; _ctr < " + argName + ".length; _ctr++) {");
+ writer.println(" if (!BufferFactory.isDirect(" + argName + "[_ctr])) {");
+ writer.println(" throw new " + getRuntimeExceptionType() + "(\"Element \" + _ctr + \" of argument \\\"" +
+ binding.getArgumentName(i) + "\\\" was not a direct buffer\");");
+ writer.println(" }");
+ writer.println(" }");
+ writer.println(" }");
}
}
}
diff --git a/src/net/java/games/gluegen/JavaType.java b/src/net/java/games/gluegen/JavaType.java
index 6e9d71c2a..2d41a543d 100644
--- a/src/net/java/games/gluegen/JavaType.java
+++ b/src/net/java/games/gluegen/JavaType.java
@@ -263,9 +263,9 @@ public class JavaType {
return "jobjectArray /*elements are String*/";
//return "jobjectArray";
}
- else if (elementType == java.nio.ByteBuffer.class)
+ else if (java.nio.Buffer.class.isAssignableFrom(elementType))
{
- return "jobjectArray /*elements are ByteBuffer*/";
+ return "jobjectArray /*elements are " + elementType.getName() + "*/";
}
else if (elementType.isArray())
{
@@ -308,6 +308,11 @@ public class JavaType {
return (this == nioByteBufferArrayType);
}
+ public boolean isNIOBufferArray() {
+ return (isArray() &&
+ (java.nio.Buffer.class.isAssignableFrom(clazz.getComponentType())));
+ }
+
public boolean isString() {
return (clazz == java.lang.String.class);
}
diff --git a/src/net/java/games/gluegen/MethodBinding.java b/src/net/java/games/gluegen/MethodBinding.java
index 5a88f00f8..fd2b7b7bc 100644
--- a/src/net/java/games/gluegen/MethodBinding.java
+++ b/src/net/java/games/gluegen/MethodBinding.java
@@ -185,7 +185,8 @@ public class MethodBinding {
Type cArgType = getCArgumentType(i);
if (javaArgType.isCompoundTypeWrapper() ||
javaArgType.isNIOBuffer() ||
- cArgType.isArray()) {
+ cArgType.isArray() ||
+ javaArgType.isNIOBufferArray()) {
// Needs unwrapping of accessors, checking of array
// lengths, or checking of direct buffer property
needsBody = true;
diff --git a/src/net/java/games/gluegen/cgram/types/Type.java b/src/net/java/games/gluegen/cgram/types/Type.java
index 531393aa5..440a762e0 100644
--- a/src/net/java/games/gluegen/cgram/types/Type.java
+++ b/src/net/java/games/gluegen/cgram/types/Type.java
@@ -225,7 +225,8 @@ public abstract class Type {
}
/** Helper method for determining how many pointer indirections this
- type represents (i.e., "void **" returns 2). */
+ type represents (i.e., "void **" returns 2). Returns 0 if this
+ type is not a pointer type. */
public int pointerDepth() {
PointerType pt = asPointer();
if (pt == null) {
@@ -234,6 +235,17 @@ public abstract class Type {
return 1 + pt.getTargetType().pointerDepth();
}
+ /** Helper method for determining how many array dimentions this
+ type represents (i.e., "char[][]" returns 2). Returns 0 if this
+ type is not an array type. */
+ public int arrayDimension() {
+ ArrayType arrayType = asArray();
+ if (arrayType == null) {
+ return 0;
+ }
+ return 1 + arrayType.getElementType().arrayDimension();
+ }
+
/** Helper routine for list equality comparison */
static boolean listsEqual(List a, List b) {
return ((a == null && b == null) ||