diff options
author | Sven Gothel <[email protected]> | 2014-06-17 01:35:28 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-06-17 01:35:28 +0200 |
commit | c3054a01990e55ab35756ea23ab7d7c05f24dd37 (patch) | |
tree | 96bd10e51cafe024a56d7b95594c7364d929c768 | |
parent | 9d857ea3575ee263801741a95711d9214c156276 (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!
11 files changed, 457 insertions, 176 deletions
diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh index c054bc1..b1089c5 100755 --- a/make/scripts/runtest.sh +++ b/make/scripts/runtest.sh @@ -80,7 +80,7 @@ function onetest() { #onetest com.jogamp.common.util.TestSystemPropsAndEnvs 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestVersionInfo 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestVersionNumber 2>&1 | tee -a $LOG -onetest com.jogamp.common.util.TestVersionSemantics 2>&1 | tee -a $LOG +#onetest com.jogamp.common.util.TestVersionSemantics 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.TestIteratorIndexCORE 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.locks.TestRecursiveLock01 2>&1 | tee -a $LOG #onetest com.jogamp.common.util.locks.TestRecursiveThreadGroupLock01 2>&1 | tee -a $LOG @@ -119,7 +119,7 @@ onetest com.jogamp.common.util.TestVersionSemantics 2>&1 | tee -a $LOG #onetest com.jogamp.common.os.TestElfReader01 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.PCPPTest 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG -#onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG +onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen01 2>&1 | tee -a $LOG #onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen02 2>&1 | tee -a $LOG 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; diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java index a97430a..79af1b7 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions 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. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,12 +20,12 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ - + package com.jogamp.gluegen.test.junit.generation; import com.jogamp.common.nio.Buffers; @@ -64,7 +64,7 @@ public class BaseClass extends JunitTracer { Assert.assertNotNull(ifName+" does not exist", clazzIf); Assert.assertNotNull(implName+" does not exist", clazzImpl); - Assert.assertEquals((int)1, clazzIf.getDeclaredField("CONSTANT_ONE").get(null)); + Assert.assertEquals(1, clazzIf.getDeclaredField("CONSTANT_ONE").get(null)); Object obj = clazzImpl.newInstance(); Assert.assertTrue("Not of type "+ifName, clazzIf.isAssignableFrom(obj.getClass())); @@ -89,27 +89,27 @@ public class BaseClass extends JunitTracer { long result = 0; long l = result; - { + { ByteBuffer bb = binding.createAPtrBlob(); PointerBuffer pb = safeByteBuffer2PointerBuffer(bb, 1); long bb2A = binding.getAPtrAddress(bb); bb2A = bb2A - 0; // avoid warning - + binding.arrayTestAVoidPtrTypeDim1Mutable(pb); pb = PointerBuffer.wrap( binding.arrayTestAVoidPtrTypeDim1Immutable(pb) ); pb = PointerBuffer.wrap( binding.arrayTestAVoidPtrTypeDim0(pb.getBuffer()) ); binding.releaseAPtrBlob( binding.getAPtrMemory( pb.get(0) ) ); - + binding.arrayTestAIntPtrTypeDim1Mutable(pb); result = binding.arrayTestAIntPtrTypeDim1Immutable(pb); result = binding.arrayTestAIntPtrTypeDim0(pb.get(0)); binding.releaseAPtrBlob( binding.getAPtrMemory( pb.get(0) ) ); - + binding.arrayTestAPtr1TypeDim1Mutable(pb); pb = PointerBuffer.wrap( binding.arrayTestAPtr1TypeDim1Immutable(pb) ); pb = PointerBuffer.wrap( binding.arrayTestAPtr1TypeDim0(pb.getBuffer()) ); binding.releaseAPtrBlob( binding.getAPtrMemory( pb.get(0) ) ); - + binding.arrayTestAPtr2TypeDim1Mutable(pb); result = binding.arrayTestAPtr2TypeDim1Immutable(pb); result = binding.arrayTestAPtr2TypeDim0(pb.get(0)); @@ -117,7 +117,7 @@ public class BaseClass extends JunitTracer { binding.releaseAPtrBlob(bb); } - + ByteBuffer bb=null; PointerBuffer pb=null; @@ -191,7 +191,7 @@ public class BaseClass extends JunitTracer { return bb; } } - + IntBuffer newIntBuffer(int size, boolean direct) { if(direct) { final IntBuffer ib = Buffers.newDirectIntBuffer(size); @@ -209,13 +209,13 @@ public class BaseClass extends JunitTracer { if(direct) { final LongBuffer lb = Buffers.newDirectLongBuffer(size); Assert.assertTrue(lb.isDirect()); - return lb; + return lb; } else { final LongBuffer lb = LongBuffer.wrap(new long[size]); Assert.assertTrue(!lb.isDirect()); Assert.assertTrue(lb.hasArray()); return lb; - } + } } PointerBuffer newPointerBuffer(int size, boolean direct) { @@ -231,15 +231,15 @@ public class BaseClass extends JunitTracer { return pb; } } - + long cleanAddress(long a) { if (Platform.is32Bit()) { return a & 0x00000000FFFFFFFFL; } else { return a; - } + } } - + PointerBuffer validatePointerBuffer(PointerBuffer pb, int elements) { Assert.assertNotNull(pb); Assert.assertEquals("PointerBuffer capacity not "+elements, elements, pb.capacity()); @@ -256,7 +256,7 @@ public class BaseClass extends JunitTracer { Assert.assertEquals("ByteBuffer remaining not PointerBuffer ELEMENT_SIZE * "+elements, elements * PointerBuffer.ELEMENT_SIZE, bb.remaining()); return validatePointerBuffer(PointerBuffer.wrap(bb), elements); } - + /** * Verifies if all methods / signatures are properly generated, * can be invoked and functions. @@ -433,7 +433,7 @@ public class BaseClass extends JunitTracer { PointerBuffer pb2 = binding.arrayTestFoo3PtrPtr(pb); validatePointerBuffer(pb2, Bindingtest1.ARRAY_SIZE); for(j=0; j<Bindingtest1.ARRAY_SIZE*Bindingtest1.ARRAY_SIZE; j++) { - Assert.assertEquals("Wrong result: s:"+lb2.get(j%Bindingtest1.ARRAY_SIZE)+" d: "+lb3.get(j), + Assert.assertEquals("Wrong result: s:"+lb2.get(j%Bindingtest1.ARRAY_SIZE)+" d: "+lb3.get(j), 1+lb2.get(j%Bindingtest1.ARRAY_SIZE), lb3.get(j)); } Assert.assertEquals(0, binding.arrayTestFoo3PtrPtrValidation(pb2, 10000)); @@ -460,14 +460,14 @@ public class BaseClass extends JunitTracer { // System.out.println("lb3: "+lb3); validatePointerBuffer(pb, Bindingtest1.ARRAY_SIZE); Assert.assertNotNull(pb.getReferencedBuffer(0)); - Assert.assertTrue("Wrong result: "+pb.getReferencedBuffer(0)+" != "+lb2, pb.getReferencedBuffer(0).equals(lb2)); + Assert.assertTrue("Wrong result: "+pb.getReferencedBuffer(0)+" != "+lb2, pb.getReferencedBuffer(0).equals(lb2)); PointerBuffer pb2 = binding.arrayTestFoo3PtrPtr(pb); // pb2 is shallow validatePointerBuffer(pb2, Bindingtest1.ARRAY_SIZE); for(j=0; j<Bindingtest1.ARRAY_SIZE; j++) { LongBuffer i64b = (LongBuffer) pb.getReferencedBuffer(j); for(i=0; i<Bindingtest1.ARRAY_SIZE; i++) { - Assert.assertEquals("Wrong result: ["+j+"]["+i+"] s:"+lb2.get(i)+" d: "+i64b.get(i), + Assert.assertEquals("Wrong result: ["+j+"]["+i+"] s:"+lb2.get(i)+" d: "+i64b.get(i), 1+lb2.get(i), i64b.get(i)); } } @@ -475,7 +475,7 @@ public class BaseClass extends JunitTracer { } // pb = PointerBuffer.alloc*(ARRAY_SIZE) - // arrayTestFoo3CopyPtrPtrA(PointerBuffer dst, PointerBuffer src) (Native deep copy w/ alloc) + // arrayTestFoo3CopyPtrPtrA(PointerBuffer dst, PointerBuffer src) (Native deep copy w/ alloc) // " " // PointerBuffer arrayTestFoo3PtrPtr(PointerBuffer) { @@ -494,13 +494,13 @@ public class BaseClass extends JunitTracer { validatePointerBuffer(pbS, Bindingtest1.ARRAY_SIZE); Assert.assertNotNull(pbS.getReferencedBuffer(0)); Assert.assertTrue("Wrong result: "+pbS.getReferencedBuffer(0)+" != "+lb2, pbS.getReferencedBuffer(0).equals(lb2)); - + PointerBuffer pbD = newPointerBuffer(Bindingtest1.ARRAY_SIZE, direct); - + // System.err.println("\n***pbS "+pbS); System.err.println("***pbD "+pbD); - binding.arrayTestFoo3CopyPtrPtrA(pbD, pbS); // pbD is shallow - validatePointerBuffer(pbD, Bindingtest1.ARRAY_SIZE); - + binding.arrayTestFoo3CopyPtrPtrA(pbD, pbS); // pbD is shallow + validatePointerBuffer(pbD, Bindingtest1.ARRAY_SIZE); + PointerBuffer pbD2 = binding.arrayTestFoo3PtrPtr(pbD); // pbD2 is shallow Assert.assertEquals(0, binding.arrayTestFoo3PtrPtrValidation(pbD, 10000)); validatePointerBuffer(pbD2, Bindingtest1.ARRAY_SIZE); @@ -525,7 +525,7 @@ public class BaseClass extends JunitTracer { } Assert.assertNotNull(e); } - + result = binding.doubleTest(context, lb, lb1, bb2, lb2); Assert.assertTrue("Wrong result: "+result, 1+10+8000+100+80000==result); @@ -601,10 +601,10 @@ public class BaseClass extends JunitTracer { i = binding.intArrayRead(null, 0, 0); Assert.assertTrue("Wrong result: "+i, 0==i); - + { long cfg_base = 0xAABBCCDD11223344L; - + PointerBuffer pb = newPointerBuffer(Bindingtest1.ARRAY_SIZE, direct); for(i=0; i<Bindingtest1.ARRAY_SIZE; i++) { long cfg_native; @@ -636,48 +636,48 @@ public class BaseClass extends JunitTracer { { long bbA, bbA2; ByteBuffer bb, bb2; - PointerBuffer bbPb; - + PointerBuffer bbPb; + final ByteBuffer blob = binding.createAPtrBlob(); final PointerBuffer blobPb = safeByteBuffer2PointerBuffer(blob, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & blobPb.get(0)); - + binding.arrayTestAVoidPtrTypeDim1Mutable(blobPb); // new memory in [0] Assert.assertTrue(DEADBEEF != ( 0xFFFFFFFF & blobPb.get(0) ) ); bb = binding.arrayTestAVoidPtrTypeDim1Immutable(blobPb); // returns memory address of [0], returned as bb (blob) bbA = cleanAddress( binding.getAPtrAddress(bb) ); // address of new memory in [0] Assert.assertEquals(blobPb.get(0), bbA); - + bbPb = safeByteBuffer2PointerBuffer(bb, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & bbPb.get(0)); Assert.assertEquals( blobPb.get(0), cleanAddress( binding.getAPtrAddress(bbPb.getBuffer()) ) ); - + bb2 = binding.arrayTestAVoidPtrTypeDim0(bb); bbA2 = cleanAddress( binding.getAPtrAddress(bb2) ); - Assert.assertEquals(bbA, bbA2); + Assert.assertEquals(bbA, bbA2); binding.releaseAPtrBlob(bb); binding.releaseAPtrBlob(blob); } - + { long bbA, bbA2; ByteBuffer bb; PointerBuffer bbPb; - + final ByteBuffer blob = binding.createAPtrBlob(); final PointerBuffer blobPb = safeByteBuffer2PointerBuffer(blob, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & blobPb.get(0)); binding.arrayTestAIntPtrTypeDim1Mutable(blobPb); // new memory in [0] Assert.assertTrue(DEADBEEF != ( 0xFFFFFFFF & blobPb.get(0) ) ); - bbA = cleanAddress( binding.arrayTestAIntPtrTypeDim1Immutable(blobPb) ); // returns memory address of [0], returned as intptr_t + bbA = cleanAddress( binding.arrayTestAIntPtrTypeDim1Immutable(blobPb) ); // returns memory address of [0], returned as intptr_t Assert.assertEquals(blobPb.get(0), bbA); bb = binding.getAPtrMemory(bbA); bbPb = safeByteBuffer2PointerBuffer(bb, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & bbPb.get(0)); - + bbA2 = cleanAddress( binding.arrayTestAIntPtrTypeDim0(bbA) ); - Assert.assertEquals(bbA, bbA2); + Assert.assertEquals(bbA, bbA2); binding.releaseAPtrBlob(bb); binding.releaseAPtrBlob(blob); } @@ -685,53 +685,53 @@ public class BaseClass extends JunitTracer { { long bbA, bbA2; ByteBuffer bb, bb2; - PointerBuffer bbPb; - + PointerBuffer bbPb; + final ByteBuffer blob = binding.createAPtrBlob(); final PointerBuffer blobPb = safeByteBuffer2PointerBuffer(blob, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & blobPb.get(0)); - + binding.arrayTestAPtr1TypeDim1Mutable(blobPb); // new memory in [0] Assert.assertTrue(DEADBEEF != ( 0xFFFFFFFF & blobPb.get(0) ) ); bb = binding.arrayTestAPtr1TypeDim1Immutable(blobPb); // returns memory address of [0], returned as bb (blob) bbA = cleanAddress( binding.getAPtrAddress(bb) ); // address of new memory in [0] Assert.assertEquals(blobPb.get(0), bbA); - + bbPb = safeByteBuffer2PointerBuffer(bb, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & bbPb.get(0)); Assert.assertEquals(blobPb.get(0), cleanAddress( binding.getAPtrAddress(bbPb.getBuffer()) ) ); - + bb2 = binding.arrayTestAPtr1TypeDim0(bb); bbA2 = cleanAddress( binding.getAPtrAddress(bb2) ); - Assert.assertEquals(bbA, bbA2); + Assert.assertEquals(bbA, bbA2); binding.releaseAPtrBlob(bb); binding.releaseAPtrBlob(blob); - + } - + { long bbA, bbA2; ByteBuffer bb; PointerBuffer bbPb; - + final ByteBuffer blob = binding.createAPtrBlob(); final PointerBuffer blobPb = safeByteBuffer2PointerBuffer(blob, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & blobPb.get(0)); binding.arrayTestAPtr2TypeDim1Mutable(blobPb); // new memory in [0] Assert.assertTrue(DEADBEEF != ( 0xFFFFFFFF & blobPb.get(0) ) ); - bbA = cleanAddress( binding.arrayTestAPtr2TypeDim1Immutable(blobPb) ); // returns memory address of [0], returned as intptr_t + bbA = cleanAddress( binding.arrayTestAPtr2TypeDim1Immutable(blobPb) ); // returns memory address of [0], returned as intptr_t Assert.assertEquals(blobPb.get(0), bbA); bb = binding.getAPtrMemory(bbA); bbPb = safeByteBuffer2PointerBuffer(bb, 1); Assert.assertEquals(DEADBEEF, 0xFFFFFFFF & bbPb.get(0)); - + bbA2 = cleanAddress( binding.arrayTestAPtr2TypeDim0(bbA) ); - Assert.assertEquals(bbA, bbA2); + Assert.assertEquals(bbA, bbA2); binding.releaseAPtrBlob(bb); binding.releaseAPtrBlob(blob); } - + } /** @@ -752,7 +752,7 @@ public class BaseClass extends JunitTracer { i = binding.intArrayRead(iarray, 0, 3); Assert.assertTrue("Wrong result: "+i, 6==i); - + final int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; final IntBuffer srcB = IntBuffer.wrap(src); { @@ -760,7 +760,7 @@ public class BaseClass extends JunitTracer { i = binding.intArrayCopy(dst, 0, src, 0, src.length); System.err.println("ArrayCopy.01: "+Arrays.toString(dst)); Assert.assertTrue("Wrong result: "+i, src.length==i); - Assert.assertTrue(Arrays.equals(src, dst)); + Assert.assertTrue(Arrays.equals(src, dst)); } { IntBuffer dstB = IntBuffer.allocate(src.length); @@ -769,7 +769,7 @@ public class BaseClass extends JunitTracer { Assert.assertTrue("Wrong result: "+i, src.length==i); Assert.assertTrue(Arrays.equals(src, dstB.array())); } - + { final int[] src36 = new int[] { 4, 5, 6, 7 }; final int[] dst = new int[src36.length]; @@ -778,7 +778,7 @@ public class BaseClass extends JunitTracer { Assert.assertTrue("Wrong result: "+i, src36.length==i); Assert.assertTrue(Arrays.equals(src36, dst)); } - + final int[] src2 = new int[] { 0, 0, 0, 4, 5, 6, 7, 0, 0, 0 }; { final int[] dst = new int[src2.length]; @@ -801,7 +801,7 @@ public class BaseClass extends JunitTracer { Assert.assertTrue(Arrays.equals(src2, dstB.array())); } } - + void assertAPTR(final long expected, final long actual) { System.err.println("0x"+Long.toHexString(expected)+" == 0x"+Long.toHexString(actual)); if (Platform.is32Bit()) { @@ -809,7 +809,7 @@ public class BaseClass extends JunitTracer { int act32; // if(Platform.isLittleEndian()) { exp32 = (int) ( expected ) ; - act32 = (int) ( actual ) ; + act32 = (int) ( actual ) ; /* } else { exp32 = (int) ( expected >> 32 ) ; act32 = (int) ( actual >> 32 ) ; @@ -818,22 +818,23 @@ public class BaseClass extends JunitTracer { Assert.assertEquals(exp32, act32); } else { Assert.assertEquals(expected, actual); - } + } } - - public void chapter09TestCompoundAndAlignment(Bindingtest1 binding) throws Exception { - + + public void chapter09TestCompoundAlignment(Bindingtest1 binding) throws Exception { + MachineDescription.StaticConfig smd = MachineDescriptionRuntime.getStatic(); MachineDescription md = MachineDescriptionRuntime.getRuntime(); - + System.err.println("static md: "+smd); System.err.println("runtime md: "+md); System.err.println("compatible static/runtime: "+md.compatible(smd.md)); - + + // Test compound alignment read { TK_ComplicatedSuperSet cs = binding.createComplicatedSuperSet(); Assert.assertEquals((byte)0xA0, cs.getBits1()); - + TK_ComplicatedSubSet sub1 = cs.getSub1(); Assert.assertEquals((byte)0xA1, sub1.getBits1()); Assert.assertEquals(0x12345678, sub1.getId()); @@ -844,11 +845,11 @@ public class BaseClass extends JunitTracer { Assert.assertEquals((byte)0xA4, sub1.getBits4()); Assert.assertEquals(256.12345f, sub1.getReal1(), 0.0); Assert.assertEquals((byte)0xA5, sub1.getBits5()); - Assert.assertEquals((long)0xdeadbeefL, sub1.getLongX()); + Assert.assertEquals(0xdeadbeefL, sub1.getLongX()); Assert.assertEquals((byte)0xA6, sub1.getBits6()); - + Assert.assertEquals((byte)0xB0, cs.getBits2()); - + TK_ComplicatedSubSet sub2 = cs.getSub2(); Assert.assertEquals((byte)0xB1, sub2.getBits1()); Assert.assertEquals(0x12345678, sub2.getId()); @@ -859,20 +860,21 @@ public class BaseClass extends JunitTracer { Assert.assertEquals((byte)0xB4, sub2.getBits4()); Assert.assertEquals(256.12345f, sub2.getReal1(), 0.0); Assert.assertEquals((byte)0xB5, sub2.getBits5()); - Assert.assertEquals((long)0xdeadbeefL, sub2.getLongX()); + Assert.assertEquals(0xdeadbeefL, sub2.getLongX()); Assert.assertEquals((byte)0xB6, sub2.getBits6()); - + Assert.assertEquals((byte)0xC0, cs.getBits3()); - + binding.destroyComplicatedSuperSet(cs); } /********************************************************************************/ + // Test compound alignment write { TK_ComplicatedSuperSet cs = TK_ComplicatedSuperSet.create(); cs.setBits1((byte)0xA0); - + TK_ComplicatedSubSet sub1 = cs.getSub1(); sub1.setBits1((byte)0xA1); sub1.setId(0x12345678); @@ -882,12 +884,12 @@ public class BaseClass extends JunitTracer { sub1.setReal0(3.1415926535897932384626433832795); sub1.setBits4((byte)0xA4); sub1.setReal1(256.12345f); - sub1.setBits5((byte)0xA5); - sub1.setLongX((long)0xdeadbeefL); + sub1.setBits5((byte)0xA5); + sub1.setLongX(0xdeadbeefL); sub1.setBits6((byte)0xA6); - + cs.setBits2((byte)0xB0); - + TK_ComplicatedSubSet sub2 = cs.getSub2(); sub2.setBits1((byte)0xB1); sub2.setId(0x12345678); @@ -897,57 +899,64 @@ public class BaseClass extends JunitTracer { sub2.setReal0(3.1415926535897932384626433832795); sub2.setBits4((byte)0xB4); sub2.setReal1(256.12345f); - sub2.setBits5((byte)0xB5); - sub2.setLongX((long)0xdeadbeefL); + sub2.setBits5((byte)0xB5); + sub2.setLongX(0xdeadbeefL); sub2.setBits6((byte)0xB6); - + cs.setBits3((byte)0xC0); - + Assert.assertTrue(binding.hasInitValues(cs)); } + } - /********************************************************************************/ - - TK_Surface surface = binding.createSurface(); - - final long surfaceContext = surface.getCtx(); + private void dumpDim(final String pre, final TK_Dimension dim) { + System.err.println(pre+dim.getX()+"/"+dim.getY()+" "+dim.getWidth()+"x"+dim.getHeight()); + } + + /** Test compound access call-by-reference */ + public void chapter10TestCompoundCallByReference(Bindingtest1 binding) throws Exception { + + final TK_Surface surface = binding.createSurface(); + + final long surfaceContext = surface.getCtx(); assertAPTR(0x123456789abcdef0L, surfaceContext); - + TK_ContextWrapper ctxWrapper = surface.getCtxWrapper(); final long wrapperContext = ctxWrapper.getCtx(); assertAPTR(0xA23456781abcdef0L, wrapperContext); - + TK_Engine engine = surface.getEngine(); final long engineContext = engine.getCtx(); assertAPTR(0xB23456782abcdef0L, engineContext); Assert.assertEquals(0x0111, engine.render(0x0100, 0x0010, 0x0001)); - + surface.setCtx(surfaceContext); assertAPTR(surfaceContext, surface.getCtx()); assertAPTR(wrapperContext, ctxWrapper.getCtx()); assertAPTR(engineContext, engine.getCtx()); Assert.assertEquals(0x0111, engine.render(0x0100, 0x0010, 0x0001)); - + ctxWrapper.setCtx(wrapperContext); assertAPTR(surfaceContext, surface.getCtx()); assertAPTR(wrapperContext, ctxWrapper.getCtx()); assertAPTR(engineContext, engine.getCtx()); Assert.assertEquals(0x0111, engine.render(0x0100, 0x0010, 0x0001)); - + engine.setCtx(engineContext); assertAPTR(surfaceContext, surface.getCtx()); assertAPTR(wrapperContext, ctxWrapper.getCtx()); assertAPTR(engineContext, engine.getCtx()); Assert.assertEquals(0x0111, engine.render(0x0100, 0x0010, 0x0001)); - + TK_Dimension dimension = surface.getBounds(); + dumpDim("ch10: ref-dim ", dimension); Assert.assertEquals(0x11111111, dimension.getX()); Assert.assertEquals(0x22222222, dimension.getY()); Assert.assertEquals(0x33333333, dimension.getWidth()); Assert.assertEquals(0x44444444, dimension.getHeight()); Assert.assertEquals(2, surface.getClipSize()); - + for(int i=0; i<surface.getClipSize(); i++) { TK_Dimension clip = surface.getClip(i); Assert.assertEquals(0x44444444 * (i+1) + 0x11111111, clip.getX()); @@ -958,4 +967,49 @@ public class BaseClass extends JunitTracer { binding.destroySurface(surface); } + /** Test compound access call-by-value */ + public void chapter11TestCompoundCallByValue(Bindingtest1 binding) throws Exception { + + { + final TK_Surface surface = binding.createSurface(); + final TK_Dimension dim0 = surface.getBounds(); + dumpDim("ch11.0: ref-dim ", dim0); + Assert.assertEquals(0x11111111, dim0.getX()); + Assert.assertEquals(0x22222222, dim0.getY()); + Assert.assertEquals(0x33333333, dim0.getWidth()); + Assert.assertEquals(0x44444444, dim0.getHeight()); + + final TK_Dimension dim1 = binding.getSurfaceBoundsValue(surface); + dumpDim("ch11.0: val-dim ", dim1); + Assert.assertEquals(0x11111111, dim1.getX()); + Assert.assertEquals(0x22222222, dim1.getY()); + Assert.assertEquals(0x33333333, dim1.getWidth()); + Assert.assertEquals(0x44444444, dim1.getHeight()); + + binding.destroySurface(surface); + } + final TK_Dimension dim0 = binding.getBoundsValue(11, 22, 33, 44); + { + dumpDim("ch11.1: val-dim ", dim0); + Assert.assertEquals(11, dim0.getX()); + Assert.assertEquals(22, dim0.getY()); + Assert.assertEquals(33, dim0.getWidth()); + Assert.assertEquals(44, dim0.getHeight()); + } + final TK_Surface surface = binding.getSurfaceValue(dim0); + final TK_Dimension dim1 = binding.getSurfaceBoundsValue(surface); + { + dumpDim("ch11.2: val-dim ", dim0); + Assert.assertEquals(11, dim1.getX()); + Assert.assertEquals(22, dim1.getY()); + Assert.assertEquals(33, dim1.getWidth()); + Assert.assertEquals(44, dim1.getHeight()); + } + final boolean sameInstanceByVal = binding.isSameInstanceByVal(dim0, dim1); + final boolean sameInstanceByRef = binding.isSameInstanceByRef(dim0, dim1); + System.err.println("ch11.3: sameInstanceByVal "+sameInstanceByVal); + System.err.println("ch11.3: sameInstanceByRef "+sameInstanceByRef); + Assert.assertFalse(sameInstanceByVal); + Assert.assertFalse(sameInstanceByRef); + } } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java index bbf0398..e63f255 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions 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. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,12 +20,12 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ - + package com.jogamp.gluegen.test.junit.generation; import java.io.IOException; @@ -109,16 +109,32 @@ public class Test1p1JavaEmitter extends BaseClass { } /** - * This covers compounds (structs) and data alignment + * This covers compounds (structs) data alignment + */ + @Test + public void chapter09TestCompoundAlignment() throws Exception { + chapter09TestCompoundAlignment(new Bindingtest1p1Impl()); + } + + /** + * This covers compounds (structs) call-by-reference + */ + @Test + public void chapter10TestCompoundCallByReference() throws Exception { + chapter10TestCompoundCallByReference(new Bindingtest1p1Impl()); + } + + /** + * This covers compounds (structs) call-by-value */ @Test - public void chapter09TestCompoundAndAlignment() throws Exception { - chapter09TestCompoundAndAlignment(new Bindingtest1p1Impl()); + public void chapter11TestCompoundCallByValue() throws Exception { + chapter11TestCompoundCallByValue(new Bindingtest1p1Impl()); } public static void main(String args[]) throws IOException { String tstname = Test1p1JavaEmitter.class.getName(); org.junit.runner.JUnitCore.main(tstname); } - + } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java index a11489c..07201c0 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java @@ -3,14 +3,14 @@ * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions 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. - * + * * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR @@ -20,18 +20,18 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of JogAmp Community. */ - + package com.jogamp.gluegen.test.junit.generation; import java.io.IOException; +import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p1Impl; import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p2Impl; - import com.jogamp.common.os.NativeLibrary; import org.junit.AfterClass; @@ -118,13 +118,29 @@ public class Test1p2ProcAddressEmitter extends BaseClass { } /** - * This covers compounds (structs) and data alignment + * This covers compounds (structs) data alignment */ @Test - public void chapter09TestCompoundAndAlignment() throws Exception { - chapter09TestCompoundAndAlignment(new Bindingtest1p2Impl()); + public void chapter09TestCompoundAlignment() throws Exception { + chapter09TestCompoundAlignment(new Bindingtest1p2Impl()); } - + + /** + * This covers compounds (structs) call-by-reference + */ + @Test + public void chapter10TestCompoundCallByReference() throws Exception { + chapter10TestCompoundCallByReference(new Bindingtest1p2Impl()); + } + + /** + * This covers compounds (structs) call-by-value + */ + @Test + public void chapter11TestCompoundCallByValue() throws Exception { + chapter11TestCompoundCallByValue(new Bindingtest1p2Impl()); + } + /** * Verifies unloading of the new library. */ @@ -134,9 +150,9 @@ public class Test1p2ProcAddressEmitter extends BaseClass { dynamicLookupHelper.close(); dynamicLookupHelper = null; } - + public static void main(String args[]) throws IOException { String tstname = Test1p2ProcAddressEmitter.class.getName(); org.junit.runner.JUnitCore.main(tstname); - } + } } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c index fda37f7..9b2fb2d 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c @@ -31,13 +31,13 @@ MYAPI void * MYAPIENTRY getAPtrMemory (const intptr_t address ) { } MYAPI void * MYAPIENTRY arrayTestAVoidPtrTypeDim0 (const void * immutable ) { - return immutable; + return (void*)immutable; } MYAPI void MYAPIENTRY arrayTestAVoidPtrTypeDim1Mutable (void ** mutable ) { *mutable = createAPtrBlob (); } MYAPI void * MYAPIENTRY arrayTestAVoidPtrTypeDim1Immutable (const void ** immutable ) { - return *immutable; + return (void*)(*immutable); } MYAPI intptr_t MYAPIENTRY arrayTestAIntPtrTypeDim0 (intptr_t immutable) { @@ -507,3 +507,24 @@ MYAPI void MYAPIENTRY destroyComplicatedSuperSet(TK_ComplicatedSuperSet * s) { free(s); } +MYAPI TK_Dimension MYAPIENTRY getBoundsValue(int32_t x, int32_t y, int32_t width, int32_t height) { + TK_Dimension r = { x, y, width, height }; + return r; +} +MYAPI TK_Surface MYAPIENTRY getSurfaceValue(TK_Dimension bounds) { + TK_Surface s; + memset(&s, 0, sizeof(s)); + s.bounds = bounds; + return s; +} +MYAPI TK_Dimension MYAPIENTRY getSurfaceBoundsValue(TK_Surface s) { + TK_Dimension res = s.bounds; + fprintf(stderr, "XXX.getSurfaceBoundsValue: dim %d/%d %dx%d\n", res.x, res.y, res.width, res.height); + return res; +} +MYAPI Bool MYAPIENTRY isSameInstanceByVal(TK_Dimension s1, TK_Dimension s2) { + return &s1 == &s2; +} +MYAPI Bool MYAPIENTRY isSameInstanceByRef(const TK_Dimension *s1, const TK_Dimension *s2) { + return s1 == s2; +} diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h index b6b6fd3..779e65d 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h @@ -240,3 +240,13 @@ MYAPI void MYAPIENTRY destroySurface(TK_Surface * surface); MYAPI TK_ComplicatedSuperSet * MYAPIENTRY createComplicatedSuperSet(); MYAPI Bool MYAPIENTRY hasInitValues(TK_ComplicatedSuperSet * s); MYAPI void MYAPIENTRY destroyComplicatedSuperSet(TK_ComplicatedSuperSet * s); + +// +// Call by Value !!! +// + +MYAPI TK_Dimension MYAPIENTRY getBoundsValue(int32_t x, int32_t y, int32_t width, int32_t height); +MYAPI TK_Surface MYAPIENTRY getSurfaceValue(TK_Dimension bounds); +MYAPI TK_Dimension MYAPIENTRY getSurfaceBoundsValue(TK_Surface s); +MYAPI Bool MYAPIENTRY isSameInstanceByVal(TK_Dimension s1, TK_Dimension s2); +MYAPI Bool MYAPIENTRY isSameInstanceByRef(const TK_Dimension *s1, const TK_Dimension *s2); |