summaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-06-17 01:35:28 +0200
committerSven Gothel <[email protected]>2014-06-17 01:35:28 +0200
commitc3054a01990e55ab35756ea23ab7d7c05f24dd37 (patch)
tree96bd10e51cafe024a56d7b95594c7364d929c768 /src/java/com/jogamp
parent9d857ea3575ee263801741a95711d9214c156276 (diff)
GlueGen: Add support for 'compound call-by-value', i.e. passing and returning struct instance
'compound call-by-value' is not efficient. However, to allow mapping APIs utilizing passing small structs as arguments and return values - this feature has been added. +++ To return the struct value, native code needs to allocate a NIO ByteBuffer and copy the data. The stack return value can be dismissed afterwards and the NIO buffer is returned. We include this functionality for all generated [impl] classes, native method: 'static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, jlong capacity)' (See: 'JavaEmitter.initClassAccessCode') Since this code requires knowledge of java classes and methods, for which a reference needs to be acquired, a static initialization method has been introduced for all generated [impl] classes: 'private static native boolean initializeImpl();' Per default the this method will be called in the new static initializer block of the class, which can be supressed via the configuration element: 'ManualStaticInit <class-name>' 'ManualStaticInit' can be used to issue the 'initializeImpl()' call in a custom static initializer written by the user. However, at the time 'initializeImpl()' gets called the JNI native library must have been loaded, of course! +++ - See tag: // FIXME: Compound call-by-value for code changes and validation of completeness Trigger for compond call-by-value in CMethodBindingEmitter is: !cArgType.isPointer() && javaArgType.isCompoundTypeWrapper() Trigger for compond call-by-value in JavaEmitter is: t.isCompound() +++ Further more we do tolerate 'javaType.isCPrimitivePointerType()', i.e. adding comments for offset/size and field entries, which are all NOP. This allows to utilize the remaining fields of the native structure. +++ Tests: Added call-by-value to test1.[ch] binding test!
Diffstat (limited to 'src/java/com/jogamp')
-rw-r--r--src/java/com/jogamp/gluegen/CMethodBindingEmitter.java52
-rw-r--r--src/java/com/jogamp/gluegen/JavaConfiguration.java18
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java140
-rw-r--r--src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java2
-rw-r--r--src/java/com/jogamp/gluegen/JavaType.java64
5 files changed, 220 insertions, 56 deletions
diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
index 242ca15..d214004 100644
--- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
@@ -302,17 +302,14 @@ public class CMethodBindingEmitter extends FunctionEmitter {
@Override
protected void emitName(PrintWriter writer) {
writer.println(); // start name on new line
- writer.print("Java_");
- writer.print(jniMangle(getJavaPackageName()));
- writer.print("_");
- writer.print(jniMangle(getJavaClassName()));
+ writer.print(JavaEmitter.getJNIMethodNamePrefix(getJavaPackageName(), getJavaClassName()));
writer.print("_");
if (isOverloadedBinding) {
writer.print(jniMangle(binding));
//System.err.println("OVERLOADED MANGLING FOR " + getName() +
// " = " + jniMangle(binding));
} else {
- writer.print(jniMangle(getName()));
+ writer.print(JavaEmitter.jniMangle(getName()));
//System.err.println(" NORMAL MANGLING FOR " + binding.getName() +
// " = " + jniMangle(getName()));
}
@@ -938,13 +935,15 @@ public class CMethodBindingEmitter extends FunctionEmitter {
writer.print(cArgType.getName());
writer.print(") ");
- if (binding.getCArgumentType(i).isPointer() && javaArgType.isPrimitive()) {
+ if (cArgType.isPointer() && javaArgType.isPrimitive()) {
writer.print("(intptr_t) ");
}
if (javaArgType.isArray() || javaArgType.isNIOBuffer() ||
javaArgType.isCompoundTypeWrapper() || javaArgType.isArrayOfCompoundTypeWrappers()) {
if( needsArrayOffset ) {
writer.print("(((char *) ");
+ } else if( !cArgType.isPointer() && javaArgType.isCompoundTypeWrapper() ) { // FIXME: Compound call-by-value
+ writer.print("*");
}
writer.print(pointerConversionArgumentName(binding.getArgumentName(i)));
if ( needsDataCopy ) {
@@ -1012,10 +1011,18 @@ public class CMethodBindingEmitter extends FunctionEmitter {
writer.print("(" + javaReturnType.jniTypeName() + ") (intptr_t) ");
}
writer.println("_res;");
- } else if (javaReturnType.isNIOBuffer() ||
- javaReturnType.isCompoundTypeWrapper()) {
+ } else if ( !cReturnType.isPointer() && javaReturnType.isCompoundTypeWrapper() ) { // FIXME: Compound call-by-value
+ final String returnSizeOf;
+ if (returnValueCapacityExpression != null) {
+ returnSizeOf = returnValueCapacityExpression.format(argumentNameArray());
+ } else {
+ returnSizeOf = "sizeof(" + cReturnType.getName() + ")";
+ }
+ writer.println(" return JVMUtil_NewDirectByteBufferCopy(env, &_res, "+returnSizeOf+");");
+ } else if (javaReturnType.isNIOBuffer() || javaReturnType.isCompoundTypeWrapper()) {
writer.println(" if (NULL == _res) return NULL;");
writer.print(" return (*env)->NewDirectByteBuffer(env, _res, ");
+
// See whether capacity has been specified
if (returnValueCapacityExpression != null) {
writer.print(
@@ -1038,11 +1045,6 @@ public class CMethodBindingEmitter extends FunctionEmitter {
"No capacity specified for java.nio.Buffer return " +
"value for function \"" + binding.getName() + "\"" +
" assuming size of equivalent C return type (sizeof(" + cReturnType.getName() + ")): " + binding);
- /**
- throw new RuntimeException(
- "No capacity specified for java.nio.Buffer return " +
- "value for function \"" + binding + "\";" +
- " C return type is " + cReturnType.getName() + ": " + binding); */
}
writer.println(");");
} else if (javaReturnType.isString()) {
@@ -1099,8 +1101,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
//writer.print(arrayRes);
//writer.println(";");
} else {
- System.err.print("Unhandled return type: ");
- javaReturnType.dump();
+ System.err.print("Unhandled return type: "+javaReturnType.getDumpString());
throw new RuntimeException("Unhandled return type");
}
}
@@ -1110,14 +1111,9 @@ public class CMethodBindingEmitter extends FunctionEmitter {
return "this0";
}
- // Mangle a class, package or function name
- protected String jniMangle(String name) {
- return name.replaceAll("_", "_1").replace('.', '_');
- }
-
protected String jniMangle(MethodBinding binding) {
StringBuilder buf = new StringBuilder();
- buf.append(jniMangle(getName()));
+ buf.append(JavaEmitter.jniMangle(getName()));
buf.append(getImplSuffix());
buf.append("__");
if (binding.hasContainingType()) {
@@ -1399,7 +1395,11 @@ public class CMethodBindingEmitter extends FunctionEmitter {
if (!needsDataCopy) {
// declare the pointer variable
writer.print(ptrTypeString);
- writer.print(" ");
+ if( !cType.isPointer() && javaType.isCompoundTypeWrapper() ) { // FIXME: Compound call-by-value
+ writer.print(" * ");
+ } else {
+ writer.print(" ");
+ }
writer.print(cVariableName);
writer.println(" = NULL;");
} else {
@@ -1444,9 +1444,15 @@ public class CMethodBindingEmitter extends FunctionEmitter {
byteOffsetVarName = null;
}
+ final String cVariableType;
+ if( !cType.isPointer() && type.isCompoundTypeWrapper() ) { // FIXME: Compound call-by-value
+ cVariableType = cType.getName()+" *";
+ } else {
+ cVariableType = cType.getName();
+ }
emitGetDirectBufferAddress(writer,
incomingArgumentName,
- cType.getName(),
+ cVariableType,
cVariableName,
byteOffsetVarName,
false);
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java
index ca7eccf..7cecbce 100644
--- a/src/java/com/jogamp/gluegen/JavaConfiguration.java
+++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java
@@ -156,6 +156,7 @@ public class JavaConfiguration {
private boolean forceUseNIODirectOnly4All = false;
private final Set<String> useNIODirectOnly = new HashSet<String>();
private final Set<String> manuallyImplement = new HashSet<String>();
+ private final Set<String> manualStaticInit = new HashSet<String>();
private final Map<String, List<String>> customJavaCode = new HashMap<String, List<String>>();
private final Map<String, List<String>> classJavadoc = new HashMap<String, List<String>>();
private final Map<String, List<String>> methodJavadoc = new HashMap<String, List<String>>();
@@ -537,6 +538,12 @@ public class JavaConfiguration {
return manuallyImplement.contains(functionName);
}
+ /** Returns true if the static initialization java code for the given class will be
+ manually implemented by the end user. */
+ public boolean manualStaticInit(String clazzName) {
+ return manualStaticInit.contains(clazzName);
+ }
+
/** Returns a list of Strings containing user-implemented code for
the given Java type name (not fully-qualified, only the class
name); returns either null or an empty list if there is no
@@ -983,6 +990,8 @@ public class JavaConfiguration {
readIgnoreField(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("ManuallyImplement")) {
readManuallyImplement(tok, filename, lineNo);
+ } else if (cmd.equalsIgnoreCase("ManualStaticInit")) {
+ readManualStaticInit(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("CustomJavaCode")) {
readCustomJavaCode(tok, filename, lineNo);
// Warning: make sure delimiters are reset at the top of this loop
@@ -1283,6 +1292,15 @@ public class JavaConfiguration {
" in file \"" + filename + "\"", e);
}
}
+ protected void readManualStaticInit(StringTokenizer tok, String filename, int lineNo) {
+ try {
+ String name = tok.nextToken();
+ manualStaticInit.add(name);
+ } catch (NoSuchElementException e) {
+ throw new RuntimeException("Error parsing \"ManualStaticInit\" command at line " + lineNo +
+ " in file \"" + filename + "\"", e);
+ }
+ }
protected void readCustomJavaCode(StringTokenizer tok, String filename, int lineNo) {
try {
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index f37f5a3..66e9b24 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -54,7 +54,6 @@ import java.nio.Buffer;
import java.util.logging.Logger;
import jogamp.common.os.MachineDescriptionRuntime;
-
import static java.util.logging.Level.*;
import static com.jogamp.gluegen.JavaEmitter.MethodAccess.*;
@@ -349,6 +348,15 @@ public class JavaEmitter implements GlueEmitter {
"\" cannot be assigned to a int, long, float, or double");
}
+ /** Mangle a class, package or function name for JNI usage, i.e. replace all '.' w/ '_' */
+ protected static String jniMangle(String name) {
+ return name.replaceAll("_", "_1").replace('.', '_');
+ }
+ /** Returns the JNI method prefix consisting our of mangled package- and class-name */
+ protected static String getJNIMethodNamePrefix(final String javaPackageName, final String javaClassName) {
+ return "Java_"+jniMangle(javaPackageName)+"_"+jniMangle(javaClassName);
+ }
+
@Override
public void emitDefine(ConstantDefinition def, String optionalComment) throws Exception {
@@ -855,7 +863,7 @@ public class JavaEmitter implements GlueEmitter {
}
jniWriter = openFile(nRoot + File.separator + containingTypeName + "_JNI.c", containingTypeName);
CodeGenUtils.emitAutogeneratedWarning(jniWriter, this);
- emitCHeader(jniWriter, containingTypeName);
+ emitCHeader(jniWriter, structClassPkg, containingTypeName);
} else {
jniWriter = null;
}
@@ -903,7 +911,7 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();");
javaWriter.println();
// generate all offset and size arrays
- generateOffsetAndSizeArrays(javaWriter, containingTypeName, structType, null); /* w/o offset */
+ generateOffsetAndSizeArrays(javaWriter, " ", containingTypeName, structType, null); /* w/o offset */
for (int i = 0; i < structType.getNumFields(); i++) {
final Field field = structType.getField(i);
final Type fieldType = field.getType();
@@ -922,14 +930,14 @@ public class JavaEmitter implements GlueEmitter {
field + "\" in type \"" + name + "\")");
}
- generateOffsetAndSizeArrays(javaWriter, fieldName, fieldType, field);
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, fieldType, field);
} else if (fieldType.isArray()) {
Type baseElementType = field.getType().asArray().getBaseElementType();
if(!baseElementType.isPrimitive())
break;
- generateOffsetAndSizeArrays(javaWriter, fieldName, null, field); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field); /* w/o size */
} else {
JavaType externalJavaType = null;
try {
@@ -941,10 +949,13 @@ public class JavaEmitter implements GlueEmitter {
}
if (externalJavaType.isPrimitive()) {
// Primitive type
- generateOffsetAndSizeArrays(javaWriter, fieldName, null, field); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field); /* w/o size */
+ } else if (externalJavaType.isCPrimitivePointerType()) {
+ // FIXME: Primitive Pointer type
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, field);
} else {
// FIXME
- LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet", new Object[]{field, name});
+ LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet: "+externalJavaType.getDumpString(), new Object[]{field, name});
// throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
// "\") not implemented yet");
}
@@ -952,7 +963,10 @@ public class JavaEmitter implements GlueEmitter {
}
}
javaWriter.println();
-
+ if (needsNativeCode) {
+ emitJavaInitCode(javaWriter, containingTypeName);
+ javaWriter.println();
+ }
javaWriter.println(" public static int size() {");
javaWriter.println(" return "+containingTypeName+"_size[mdIdx];");
javaWriter.println(" }");
@@ -1050,8 +1064,7 @@ public class JavaEmitter implements GlueEmitter {
}
} else if (fieldType.isCompound()) {
// FIXME: will need to support this at least in order to
- // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate
- // a name?)
+ // handle the union in jawt_Win32DrawingSurfaceInfo (fabricate a name?)
if (fieldType.getName() == null) {
throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
field + "\" in type \"" + name + "\")");
@@ -1139,6 +1152,10 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
}
javaWriter.println(" }");
+ } else if (javaType.isCPrimitivePointerType()) {
+ // FIXME: Primitive Pointer type
+ javaWriter.println();
+ javaWriter.println(" /** "+fieldName +": "+javaType.getDumpString()+" */");
}
}
}
@@ -1191,9 +1208,9 @@ public class JavaEmitter implements GlueEmitter {
writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(" + paramTypeName + " val)");
}
- private void generateOffsetAndSizeArrays(PrintWriter writer, String fieldName, Type fieldType, Field field) {
+ private void generateOffsetAndSizeArrays(PrintWriter writer, String prefix, String fieldName, Type fieldType, Field field) {
if(null != field) {
- writer.print(" private static final int[] "+fieldName+"_offset = new int[] { ");
+ writer.print(prefix+"private static final int[] "+fieldName+"_offset = new int[] { ");
for( int i=0; i < machDescTargetConfigs.length; i++ ) {
if(0<i) {
writer.print(", ");
@@ -1204,7 +1221,7 @@ public class JavaEmitter implements GlueEmitter {
writer.println(" };");
}
if(null!=fieldType) {
- writer.print(" private static final int[] "+fieldName+"_size = new int[] { ");
+ writer.print(prefix+"private static final int[] "+fieldName+"_size = new int[] { ");
for( int i=0; i < machDescTargetConfigs.length; i++ ) {
if(0<i) {
writer.print(", ");
@@ -1308,7 +1325,7 @@ public class JavaEmitter implements GlueEmitter {
} else if (targetType.isDouble()) {
return JavaType.createForCDoublePointer();
} else if (targetType.isCompound()) {
- if (t.isArray()) {
+ if (t.isArray()) { // FIXME: Compound and Compound-Arrays
throw new RuntimeException("Arrays of compound types not handled yet");
}
// Special cases for known JNI types (in particular for converting jawt.h)
@@ -1316,7 +1333,6 @@ public class JavaEmitter implements GlueEmitter {
t.getName().equals("jobject")) {
return javaType(java.lang.Object.class);
}
-
String name = targetType.getName();
if (name == null) {
// Try containing pointer type for any typedefs
@@ -1393,6 +1409,12 @@ public class JavaEmitter implements GlueEmitter {
t.arrayDimension() + " targetType=\"" + targetType + "\"]");
}
+ } else if(t.isCompound() ) { // FIXME: Compound and Compound-Arrays
+ final String 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(
"Could not convert C type \"" + t + "\" (class " +
@@ -1673,7 +1695,8 @@ public class JavaEmitter implements GlueEmitter {
}
if (cfg.emitImpl()) {
- emitCHeader(cWriter(), cfg.implClassName());
+ emitJavaInitCode();
+ emitCHeader(cWriter(), getImplPackageName(), cfg.implClassName());
}
} catch (Exception e) {
throw new RuntimeException(
@@ -1684,22 +1707,103 @@ public class JavaEmitter implements GlueEmitter {
}
- protected void emitCHeader(PrintWriter cWriter, String className) {
+ private static final String initClassAccessCode = "\n"+
+ "static const char * clazzNameBuffers = \"com/jogamp/common/nio/Buffers\";\n"+
+ "static const char * clazzNameBuffersStaticNewCstrName = \"newDirectByteBuffer\";\n"+
+ "static const char * clazzNameBuffersStaticNewCstrSignature = \"(I)Ljava/nio/ByteBuffer;\";\n"+
+ "static jclass clazzBuffers = NULL;\n"+
+ "static jmethodID cstrBuffersNew = NULL;\n"+
+ "\n"+
+ "static jboolean _initClazzAccess(JNIEnv *env) {\n"+
+ " jclass c;\n"+
+ "\n"+
+ " if(NULL!=cstrBuffersNew) return JNI_TRUE;\n"+
+ "\n"+
+ " c = (*env)->FindClass(env, clazzNameBuffers);\n"+
+ " if(NULL==c) {\n"+
+ " fprintf(stderr, \"FatalError: Can't find %s\\n\", clazzNameBuffers);\n"+
+ " (*env)->FatalError(env, clazzNameBuffers);\n"+
+ " return JNI_FALSE;\n"+
+ " }\n"+
+ " clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);\n"+
+ " if(NULL==clazzBuffers) {\n"+
+ " fprintf(stderr, \"FatalError: Can't use %s\\n\", clazzNameBuffers);\n"+
+ " (*env)->FatalError(env, clazzNameBuffers);\n"+
+ " return JNI_FALSE;\n"+
+ " }\n"+
+ "\n"+
+ " cstrBuffersNew = (*env)->GetStaticMethodID(env, clazzBuffers,\n"+
+ " clazzNameBuffersStaticNewCstrName, clazzNameBuffersStaticNewCstrSignature);\n"+
+ " if(NULL==cstrBuffersNew) {\n"+
+ " fprintf(stderr, \"FatalError: Java_jogamp_common_jvm_JVMUtil:: can't create %s.%s %s\\n\",\n"+
+ " clazzNameBuffers,\n"+
+ " clazzNameBuffersStaticNewCstrName, clazzNameBuffersStaticNewCstrSignature);\n"+
+ " (*env)->FatalError(env, clazzNameBuffersStaticNewCstrName);\n"+
+ " return JNI_FALSE;\n"+
+ " }\n"+
+ " return JNI_TRUE;\n"+
+ "}\n"+
+ "\n"+
+ "static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, jlong capacity) {\n"+
+ " jobject jbyteBuffer = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffersNew, capacity);\n"+
+ " void * byteBufferPtr = (*env)->GetDirectBufferAddress(env, jbyteBuffer);\n"+
+ " memcpy(byteBufferPtr, source_address, capacity);\n"+
+ " return jbyteBuffer;\n"+
+ "}\n"+
+ "\n";
+
+ private static final String staticClassInitCode = "\n"+
+ " static {\n"+
+ " if( !initializeImpl() ) {\n"+
+ " throw new RuntimeException(\"Initialization failure\");\n"+
+ " }\n"+
+ " }\n"+
+ "\n";
+
+ protected void emitCHeader(PrintWriter cWriter, String packageName, String className) {
cWriter.println("#include <jni.h>");
cWriter.println("#include <stdlib.h>");
+ cWriter.println("#include <string.h>");
cWriter.println();
if (getConfig().emitImpl()) {
cWriter.println("#include <assert.h>");
cWriter.println();
}
-
+ emitCInitCode(cWriter, packageName, className);
for (String code : cfg.customCCode()) {
cWriter.println(code);
}
cWriter.println();
}
+ protected void emitCInitCode(PrintWriter cWriter, String packageName, String className) {
+ if (getConfig().emitImpl()) {
+ cWriter.println(initClassAccessCode);
+ cWriter.println("JNIEXPORT jboolean JNICALL "+JavaEmitter.getJNIMethodNamePrefix(packageName, className)+"_initializeImpl(JNIEnv *env, jclass _unused) {");
+ cWriter.println(" return _initClazzAccess(env);");
+ cWriter.println("}");
+ cWriter.println();
+ }
+ }
+ protected void emitJavaInitCode() {
+ if ( cfg.allStatic() ) {
+ emitJavaInitCode( javaWriter(), cfg.className() );
+ } else if( cfg.emitImpl() ) {
+ emitJavaInitCode( javaImplWriter(), cfg.implClassName() );
+ }
+ }
+ protected void emitJavaInitCode(PrintWriter jWriter, String className) {
+ if( null != jWriter ) {
+ jWriter.println();
+ jWriter.println(" private static native boolean initializeImpl();");
+ jWriter.println();
+ if( !cfg.manualStaticInit(className) ) {
+ jWriter.println(staticClassInitCode);
+ }
+ }
+ }
+
/**
* Write out any footer information for the output files (closing brace of
* class definition, etc).
diff --git a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
index 8c9f8bf..5dc5eda 100644
--- a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
@@ -462,7 +462,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
"(\"Length of array \\\"" + getArgumentName(i) +
"\\\" was less than the required " + arrayType.getLength() + "\");");
// FIXME: What is this ??? Until resolved - throw an exception !
- throw new RuntimeException("????? "+binding+": binding.getCArgumentType("+i+").isArray(): "+type);
+ throw new RuntimeException("????? "+binding+": binding.getCArgumentType("+i+").isArray(): "+type); // FIXME: Compound and Compound-Arrays
} else {
JavaType javaType = binding.getJavaArgumentType(i);
if (javaType.isNIOBuffer()) {
diff --git a/src/java/com/jogamp/gluegen/JavaType.java b/src/java/com/jogamp/gluegen/JavaType.java
index a9e1941..5f4b97a 100644
--- a/src/java/com/jogamp/gluegen/JavaType.java
+++ b/src/java/com/jogamp/gluegen/JavaType.java
@@ -487,14 +487,50 @@ public class JavaType {
// Internals only below this point
//
+ private void append(final StringBuilder sb, final String val, final boolean prepComma) {
+ if( prepComma ) {
+ sb.append(", ");
+ }
+ sb.append(val);
+ }
// For debugging
public String getDumpString() {
- return "[clazz = " + clazz + " , name = " + name + " , elementType = " + elementType + " , primitivePointerType = " + primitivePointerType +
- ", isArray "+isArray()+", isArrayOfCompoundTypeWrappers "+isArrayOfCompoundTypeWrappers()+
- ", isNIOBuffer "+isNIOBuffer()+", isNIOBufferArray "+isNIOBufferArray()+"]";
- }
- public void dump() {
- System.err.println(getDumpString());
+ final StringBuilder sb = new StringBuilder();
+ sb.append("JavaType[");
+ boolean prepComma = false;
+ if( null != clazz ) {
+ append(sb, "clazz = "+clazz.getName(), prepComma); prepComma=true;
+ }
+ if( null != name ) {
+ append(sb, "name = "+name, prepComma); prepComma=true;
+ }
+ if( null != elementType ) {
+ append(sb, "elementType = "+elementType, prepComma); prepComma=true;
+ }
+ if( null != primitivePointerType ) {
+ append(sb, "primitivePointerType = "+primitivePointerType, prepComma); prepComma=true;
+ }
+ append(sb, "is[", prepComma); prepComma=false;
+ if( isArray() ) {
+ append(sb, "array", prepComma); prepComma=true;
+ }
+ if( isArrayOfCompoundTypeWrappers() ) {
+ append(sb, "compoundArray", prepComma); prepComma=true;
+ }
+ if( isCompoundTypeWrapper() ) {
+ append(sb, "compound", prepComma); prepComma=true;
+ }
+ if( isNIOBuffer() ) {
+ append(sb, "nioBuffer", prepComma); prepComma=true;
+ }
+ if( isNIOBufferArray() ) {
+ append(sb, "nioBufferArray", prepComma); prepComma=true;
+ }
+ if( isCPrimitivePointerType() ) {
+ append(sb, "C-Primitive-Pointer", prepComma); prepComma=true;
+ }
+ sb.append("]]");
+ return sb.toString();
}
/**
@@ -516,14 +552,6 @@ public class JavaType {
this.elementType = null;
}
- /** Constructs a type representing an array of C pointers. */
- private JavaType(Type elementType) {
- this.primitivePointerType = null;
- this.clazz = null;
- this.name = null;
- this.elementType = elementType;
- }
-
/** Constructs a type representing a pointer to a C primitive
(integer, floating-point, or void pointer) type. */
private JavaType(C_PTR primitivePointerType) {
@@ -533,6 +561,14 @@ public class JavaType {
this.elementType = null;
}
+ /** Constructs a type representing an array of C pointers. */
+ private JavaType(Type elementType) {
+ this.primitivePointerType = null;
+ this.clazz = null;
+ this.name = null;
+ this.elementType = elementType;
+ }
+
private JavaType(C_PTR primitivePointerType, Class<?> clazz, String name, Type elementType) {
this.primitivePointerType = primitivePointerType;
this.clazz = clazz;