diff options
author | Sven Gothel <[email protected]> | 2010-03-28 01:27:01 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-03-28 01:27:01 +0100 |
commit | a41f4d504d2f8cf58114d570d23f757ab2659cfc (patch) | |
tree | ebe021734de27004c1424130b0150f0b3cc2b5bb /src/java/com/sun/gluegen | |
parent | 2b61964060ffb79a313030d795ad069fbbe97b88 (diff) |
http://www.jogamp.org/bugzilla/show_bug.cgi?id=389
Mixed types in generated code are functioning now,
even though not all permutations are generated - still.
However, this patch merges the indirect object passing,
wheather it is a primitive array or an indirect NIO buffer,
incl. PointerBuffer.
This allows the usage of only one JNI functions for all combinations.
Only in case of NIODirectOnly, the simplified direct only '0'
variation is created - otherwise the parametrized '1' variant.
The junit tests proves the implementation and
almost completes the gluegen junit tests coverage
for JavaEmitter and ProcAddressEmitter.
Impact/Result:
- Working mixed array types
- JOGL GL2 native library shrunk around 30%
- Simplified gluegen code
- Almost complete gluegen junit tests
TODO: Complete permutations of array/NIO arguments,
if desired.
++++
Misc changes:
- NativeLibrary implements DynamicLookupHelper:
lookupFunction() -> dynamicLookupFunction()
Diffstat (limited to 'src/java/com/sun/gluegen')
7 files changed, 163 insertions, 320 deletions
diff --git a/src/java/com/sun/gluegen/CMethodBindingEmitter.java b/src/java/com/sun/gluegen/CMethodBindingEmitter.java index 91e3f99..c91e992 100644 --- a/src/java/com/sun/gluegen/CMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/CMethodBindingEmitter.java @@ -103,16 +103,6 @@ public class CMethodBindingEmitter extends FunctionEmitter */ private MessageFormat returnValueLengthExpression = null; - // Note: the VC++ 6.0 compiler emits hundreds of warnings when the - // (necessary) null-checking code is enabled. This appears to just - // be a compiler bug, but would be good to track down exactly why it - // is happening. When the null checking is enabled for just the - // GetPrimitiveArrayCritical calls, there are five warnings - // generated for several thousand new if tests added to the code. - // Which ones are the ones at fault? The line numbers for the - // warnings are incorrect. - private static final boolean EMIT_NULL_CHECKS = true; - protected static final String STRING_CHARS_PREFIX = "_strchars_"; // We need this in order to compute sizes of certain types @@ -369,6 +359,9 @@ public class CMethodBindingEmitter extends FunctionEmitter if (javaArgType.isPrimitiveArray() || javaArgType.isNIOBuffer()) { writer.print(", jint " + byteOffsetArgName(i)); + if(forIndirectBufferAndArrayImplementation) { + writer.print(", jboolean " + isNIOArgName(i)); + } } else if (javaArgType.isNIOBufferArray()) { writer.print(", jintArray " + byteOffsetArrayArgName(i)); @@ -383,12 +376,10 @@ public class CMethodBindingEmitter extends FunctionEmitter // writer.println("printf(\" - - - - "+ getName() + getImplSuffix() +" - - - -\\n\");"); emitBodyVariableDeclarations(writer); emitBodyUserVariableDeclarations(writer); - emitBodyVariablePreCallSetup(writer, false); - emitBodyVariablePreCallSetup(writer, true); + emitBodyVariablePreCallSetup(writer); emitBodyCallCFunction(writer); emitBodyUserVariableAssignments(writer); - emitBodyVariablePostCallCleanup(writer, true); - emitBodyVariablePostCallCleanup(writer, false); + emitBodyVariablePostCallCleanup(writer); emitBodyReturnResult(writer); writer.println("}"); writer.println(); @@ -548,22 +539,21 @@ public class CMethodBindingEmitter extends FunctionEmitter * emitBodyVariableDeclarations(), PRIOR TO calling the actual C * function. */ - protected void emitBodyVariablePreCallSetup(PrintWriter writer, boolean emittingPrimitiveArrayCritical) { + protected void emitBodyVariablePreCallSetup(PrintWriter writer) { - if (!emittingPrimitiveArrayCritical) { - // Convert all Buffers to pointers first so we don't have to - // call ReleasePrimitiveArrayCritical for any arrays if any - // incoming buffers aren't direct - if (binding.hasContainingType()) { + // Convert all Buffers to pointers first so we don't have to + // call ReleasePrimitiveArrayCritical for any arrays if any + // incoming buffers aren't direct + if (binding.hasContainingType()) { emitPointerConversion(writer, binding, binding.getContainingType(), binding.getContainingCType(), JavaMethodBindingEmitter.javaThisArgumentName(), CMethodBindingEmitter.cThisArgumentName(), null); - } + } - for (int i = 0; i < binding.getNumArguments(); i++) { + for (int i = 0; i < binding.getNumArguments(); i++) { JavaType type = binding.getJavaArgumentType(i); if (type.isJNIEnv() || binding.isArgumentThisPointer(i)) { continue; @@ -577,7 +567,6 @@ public class CMethodBindingEmitter extends FunctionEmitter pointerConversionArgumentName(javaArgName), byteOffsetArgName(i)); } - } } // Convert all arrays to pointers, and get UTF-8 versions of jstring args @@ -594,19 +583,7 @@ public class CMethodBindingEmitter extends FunctionEmitter javaArgType.isArrayOfCompoundTypeWrappers()) { boolean needsDataCopy = javaArgTypeNeedsDataCopy(javaArgType); - // We only defer the emission of GetPrimitiveArrayCritical - // calls that won't be matched up until after the function - // we're calling - if ((!needsDataCopy && !emittingPrimitiveArrayCritical) || - (needsDataCopy && emittingPrimitiveArrayCritical)) { - continue; - } - - if (EMIT_NULL_CHECKS) { - writer.print(" if ("); - writer.print(javaArgName); - writer.println(" != NULL) {"); - } + writer.println(" if ( NULL != " + javaArgName + " ) {"); Type cArgType = binding.getCArgumentType(i); String cArgTypeName = cArgType.getName(); @@ -622,12 +599,10 @@ public class CMethodBindingEmitter extends FunctionEmitter cArgTypeName = "jstring *"; } writer.print(cArgTypeName); - writer.print(") (((char*) (*env)->GetPrimitiveArrayCritical(env, "); - writer.print(javaArgName); - writer.println(", NULL)) + " + byteOffsetArgName(i) + ");"); -//if(cargtypename is void*) -// _ptrX = ((char*)convName + index1*sizeof(thisArgsJavaType)); - + writer.print(") (((char*) ( JNI_TRUE == " + isNIOArgName(i) + " ? "); + writer.print(" (*env)->GetDirectBufferAddress(env, " + javaArgName + ") : "); + writer.print(" (*env)->GetPrimitiveArrayCritical(env, " + javaArgName + ", NULL) ) ) + "); + writer.println(byteOffsetArgName(i) + ");"); } else { // Handle the case where the array elements are of a type that needs a // data copy operation to convert from the java memory model to the C @@ -761,14 +736,9 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(); } // end of data copy - if (EMIT_NULL_CHECKS) { - writer.println(" }"); - } - } else if (javaArgType.isString()) { - if (!emittingPrimitiveArrayCritical) { - continue; - } + writer.println(" }"); + } else if (javaArgType.isString()) { emitGetStringChars(writer, javaArgName, STRING_CHARS_PREFIX + javaArgName, isUTF8Type(binding.getCArgumentType(i)), @@ -782,7 +752,7 @@ public class CMethodBindingEmitter extends FunctionEmitter * Code to clean up any variables that were declared in * emitBodyVariableDeclarations(), AFTER calling the actual C function. */ - protected void emitBodyVariablePostCallCleanup(PrintWriter writer, boolean emittingPrimitiveArrayCritical) { + protected void emitBodyVariablePostCallCleanup(PrintWriter writer) { // Release primitive arrays and temporary UTF8 strings if necessary for (int i = 0; i < binding.getNumArguments(); i++) { @@ -799,27 +769,16 @@ public class CMethodBindingEmitter extends FunctionEmitter javaArgType.isArrayOfCompoundTypeWrappers()) { boolean needsDataCopy = javaArgTypeNeedsDataCopy(javaArgType); - if ((!needsDataCopy && !emittingPrimitiveArrayCritical) || - (needsDataCopy && emittingPrimitiveArrayCritical)) { - continue; - } - - if (EMIT_NULL_CHECKS) { - writer.print(" if ("); - writer.print(javaArgName); - writer.println(" != NULL) {"); - } - String convName = pointerConversionArgumentName(javaArgName); if (!needsDataCopy) { + writer.println(" if ( NULL != " + javaArgName + " && JNI_FALSE == " + isNIOArgName(i) + " ) {"); + // Release array - writer.print(" (*env)->ReleasePrimitiveArrayCritical(env, "); - writer.print(javaArgName); - writer.print(", "); - writer.print(convName); - writer.println(", 0);"); + writer.print(" (*env)->ReleasePrimitiveArrayCritical(env, " + javaArgName + ", " + convName + ", 0);"); } else { + writer.println(" if ( NULL != " + javaArgName + " ) {"); + // clean up the case where the array elements are of a type that needed // a data copy operation to convert from the java memory model to the // C memory model (e.g., int[][], String[], etc) @@ -909,19 +868,10 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(");"); } // end of cleaning up copied data - if (EMIT_NULL_CHECKS) { - writer.println(" }"); - } - } else if (javaArgType.isString()) { - if (emittingPrimitiveArrayCritical) { - continue; - } + writer.println(" }"); - if (EMIT_NULL_CHECKS) { - writer.print(" if ("); - writer.print(javaArgName); - writer.println(" != NULL) {"); - } + } else if (javaArgType.isString()) { + writer.println(" if ( NULL != " + javaArgName + " ) {"); if (isUTF8Type(cArgType)) { writer.print(" (*env)->ReleaseStringUTFChars(env, "); @@ -933,9 +883,7 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(" free((void*) " + STRING_CHARS_PREFIX + javaArgName + ");"); } - if (EMIT_NULL_CHECKS) { - writer.println(" }"); - } + writer.println(" }"); } } } @@ -1038,7 +986,7 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println("_res;"); } else if (javaReturnType.isNIOBuffer() || javaReturnType.isCompoundTypeWrapper()) { - writer.println(" if (_res == NULL) return NULL;"); + writer.println(" if (NULL == _res) return NULL;"); writer.print(" return (*env)->NewDirectByteBuffer(env, _res, "); // See whether capacity has been specified if (returnValueCapacityExpression != null) { @@ -1065,11 +1013,11 @@ public class CMethodBindingEmitter extends FunctionEmitter } writer.println(");"); } else if (javaReturnType.isString()) { - writer.print(" if (_res == NULL) return NULL;"); + writer.println(" if (NULL == _res) return NULL;"); writer.println(" return (*env)->NewStringUTF(env, _res);"); } else if (javaReturnType.isArrayOfCompoundTypeWrappers() || (javaReturnType.isArray() && javaReturnType.isNIOByteBufferArray())) { - writer.println(" if (_res == NULL) return NULL;"); + writer.println(" if (NULL == _res) return NULL;"); if (returnValueLengthExpression == null) { throw new RuntimeException("Error while generating C code: no length specified for array returned from function " + binding); @@ -1163,6 +1111,9 @@ public class CMethodBindingEmitter extends FunctionEmitter // extra arguments if (type.isNIOBuffer()) { jniMangle(Integer.TYPE, buf, false); + if(forIndirectBufferAndArrayImplementation) { + jniMangle(Boolean.TYPE, buf, false); + } } else if (type.isNIOBufferArray()) { int[] intArrayType = new int[0]; c = intArrayType.getClass(); @@ -1239,9 +1190,7 @@ public class CMethodBindingEmitter extends FunctionEmitter } private void emitOutOfMemoryCheck(PrintWriter writer, String varName, String errorMessage) { - writer.print(" if ("); - writer.print(varName); - writer.println(" == NULL) {"); + writer.println(" if ( NULL == " + varName + " ) {"); writer.println(" (*env)->ThrowNew(env, (*env)->FindClass(env, \"java/lang/OutOfMemoryError\"),"); writer.print(" \"" + errorMessage); writer.print(" in native dispatcher for \\\""); @@ -1274,11 +1223,7 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(elementTypeString); writer.println("));"); // Catch memory allocation failure - if (EMIT_NULL_CHECKS) { - emitOutOfMemoryCheck( - writer, targetVarName, - mallocFailureErrorString); - } + emitOutOfMemoryCheck( writer, targetVarName, mallocFailureErrorString); } private void emitCalloc(PrintWriter writer, @@ -1296,11 +1241,7 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(elementTypeString); writer.println("));"); // Catch memory allocation failure - if (EMIT_NULL_CHECKS) { - emitOutOfMemoryCheck( - writer, targetVarName, - mallocFailureErrorString); - } + emitOutOfMemoryCheck( writer, targetVarName, mallocFailureErrorString); } private void emitGetStringChars(PrintWriter writer, @@ -1308,11 +1249,8 @@ public class CMethodBindingEmitter extends FunctionEmitter String receivingVarName, boolean isUTF8, boolean emitElseClause) { - if (EMIT_NULL_CHECKS) { - writer.print(" if ("); - writer.print(sourceVarName); - writer.println(" != NULL) {"); - } + writer.println(" if ( NULL != " + sourceVarName + " ) {"); + if (isUTF8) { writer.print(" "); writer.print(receivingVarName); @@ -1321,11 +1259,7 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.println(", (jboolean*)NULL);"); // Catch memory allocation failure in the event that the VM didn't pin // the String and failed to allocate a copy - if (EMIT_NULL_CHECKS) { - emitOutOfMemoryCheck( - writer, receivingVarName, - "Failed to get UTF-8 chars for argument \\\""+sourceVarName+"\\\""); - } + emitOutOfMemoryCheck( writer, receivingVarName, "Failed to get UTF-8 chars for argument \\\""+sourceVarName+"\\\""); } else { // The UTF-16 case is basically Windows specific. Unix platforms // tend to use only the UTF-8 encoding. On Windows the problem @@ -1341,17 +1275,15 @@ public class CMethodBindingEmitter extends FunctionEmitter "Could not allocate temporary buffer for copying string argument \\\""+sourceVarName+"\\\""); writer.println(" (*env)->GetStringRegion(env, " + sourceVarName + ", 0, (*env)->GetStringLength(env, " + sourceVarName + "), " + receivingVarName + ");"); } - if (EMIT_NULL_CHECKS) { - writer.print(" }"); - if (emitElseClause) { - writer.print(" else {"); - writer.print(" "); - writer.print(receivingVarName); - writer.println(" = NULL;"); - writer.println(" }"); - } else { - writer.println(); - } + writer.print(" }"); + if (emitElseClause) { + writer.print(" else {"); + writer.print(" "); + writer.print(receivingVarName); + writer.println(" = NULL;"); + writer.println(" }"); + } else { + writer.println(); } } @@ -1361,12 +1293,8 @@ public class CMethodBindingEmitter extends FunctionEmitter String receivingVarName, String byteOffsetVarName, boolean emitElseClause) { - if (EMIT_NULL_CHECKS) { - writer.print(" if ("); - writer.print(sourceVarName); - writer.println(" != NULL) {"); - writer.print(" "); - } + writer.println(" if ( NULL != " + sourceVarName + " ) {"); + writer.print(" "); writer.print(" "); writer.print(receivingVarName); @@ -1377,17 +1305,15 @@ public class CMethodBindingEmitter extends FunctionEmitter writer.print(sourceVarName); writer.println(")) + " + ((byteOffsetVarName != null) ? byteOffsetVarName : "0") + ");"); - if (EMIT_NULL_CHECKS) { - writer.print(" }"); - if (emitElseClause) { - writer.println(" else {"); - writer.print(" "); - writer.print(receivingVarName); - writer.println(" = NULL;"); - writer.println(" }"); - } else { - writer.println(); - } + writer.print(" }"); + if (emitElseClause) { + writer.println(" else {"); + writer.print(" "); + writer.print(receivingVarName); + writer.println(" = NULL;"); + writer.println(" }"); + } else { + writer.println(); } } @@ -1504,6 +1430,14 @@ public class CMethodBindingEmitter extends FunctionEmitter return s + "_byte_offset"; } + protected String isNIOArgName(int i) { + return isNIOArgName(binding.getArgumentName(i)); + } + + protected String isNIOArgName(String s) { + return s + "_is_nio"; + } + protected String byteOffsetArrayArgName(int i) { return binding.getArgumentName(i) + "_byte_offset_array"; } diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java index df98839..b2f7578 100644 --- a/src/java/com/sun/gluegen/JavaEmitter.java +++ b/src/java/com/sun/gluegen/JavaEmitter.java @@ -586,36 +586,6 @@ public class JavaEmitter implements GlueEmitter { emitter.addModifier(JavaMethodBindingEmitter.NATIVE); emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); allEmitters.add(emitter); - - // Optionally emit the entry point taking arrays which handles - // both the public entry point taking arrays as well as the - // indirect buffer case - if (!cfg.nioDirectOnly(binding.getName()) && - binding.signatureCanUseIndirectNIO()) { - emitter = - new JavaMethodBindingEmitter(binding, - writer, - cfg.runtimeExceptionType(), - cfg.unsupportedExceptionType(), - false, - cfg.tagNativeBinding(), - true, - false, - true, - false, - true, - false, - false, - cfg); - - emitter.addModifier(JavaMethodBindingEmitter.PRIVATE); - if (cfg.allStatic()) { - emitter.addModifier(JavaMethodBindingEmitter.STATIC); - } - emitter.addModifier(JavaMethodBindingEmitter.NATIVE); - emitter.setReturnedArrayLengthExpression(cfg.returnedArrayLength(binding.getName())); - allEmitters.add(emitter); - } } } @@ -656,51 +626,27 @@ public class JavaEmitter implements GlueEmitter { } } - CMethodBindingEmitter cEmitter = - new CMethodBindingEmitter(binding, - cWriter(), - cfg.implPackageName(), - cfg.implClassName(), - true, /* NOTE: we always disambiguate with a suffix now, so this is optional */ - cfg.allStatic(), - (binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue), - false, - machDesc64); - if (returnValueCapacityFormat != null) { - cEmitter.setReturnValueCapacityExpression(returnValueCapacityFormat); - } - if (returnValueLengthFormat != null) { - cEmitter.setReturnValueLengthExpression(returnValueLengthFormat); - } - cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName())); - cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName())); - allEmitters.add(cEmitter); - - // Now see if we have to emit another entry point to handle the - // indirect buffer and array case - if (binding.argumentsUseNIO() && - binding.signatureCanUseIndirectNIO() && - !cfg.nioDirectOnly(binding.getName())) { - cEmitter = + CMethodBindingEmitter cEmitter; + // Generate a binding without mixed access (NIO-direct, -indirect, array) + cEmitter = new CMethodBindingEmitter(binding, cWriter(), cfg.implPackageName(), cfg.implClassName(), - true, /* NOTE: we always disambiguate with a suffix now, so this is optional */ + true, // NOTE: we always disambiguate with a suffix now, so this is optional cfg.allStatic(), - binding.needsNIOWrappingOrUnwrapping(), - true, + (binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue), + !cfg.nioDirectOnly(binding.getName()), machDesc64); - if (returnValueCapacityFormat != null) { + if (returnValueCapacityFormat != null) { cEmitter.setReturnValueCapacityExpression(returnValueCapacityFormat); - } - if (returnValueLengthFormat != null) { + } + if (returnValueLengthFormat != null) { cEmitter.setReturnValueLengthExpression(returnValueLengthFormat); - } - cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName())); - cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName())); - allEmitters.add(cEmitter); } + cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName())); + cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName())); + allEmitters.add(cEmitter); } } @@ -746,14 +692,15 @@ public class JavaEmitter implements GlueEmitter { // Implementation class: // public void fooMethod(Buffer arg) { // ... bounds checks, etc. ... - // if (arg.isDirect()) { - // fooMethod0(arg, computeDirectBufferByteOffset(arg)); - // } else { - // fooMethod1(getIndirectBufferArray(arg), computeIndirectBufferByteOffset(arg)); - // } + // + // boolean arg_direct = arg != null && BufferFactory.isDirect(arg); + // + // fooMethod0(arg_direct?arg:BufferFactory.getArray(arg), + // arg_direct?BufferFactory.getDirectBufferByteOffset(arg):BufferFactory.getIndirectBufferByteOffset(arg), + // arg_direct, + // ... ); // } - // private native void fooMethod0(Object arg, int arg_byte_offset); - // private native void fooMethod1(Object arg, int arg_byte_offset); + // private native void fooMethod0(Object arg, int arg_byte_offset, boolean arg_is_direct, ...); // // Method taking primitive array argument: // Interface class: @@ -772,8 +719,7 @@ public class JavaEmitter implements GlueEmitter { // fooMethod1(getIndirectBufferArray(arg), computeIndirectBufferByteOffset(arg)); // } // } - // private native void fooMethod0(Object arg, int arg_byte_offset); - // private native void fooMethod1(Object arg, int arg_byte_offset); + // private native void fooMethod0(Object arg, int arg_byte_offset, boolean arg_is_direct, ...); // // Note in particular that the public entry point taking an // array is merely a special case of the indirect buffer case. @@ -1947,4 +1893,4 @@ public class JavaEmitter implements GlueEmitter { return Character.toUpperCase(string.charAt(0)) + string.substring(1); } -}
\ No newline at end of file +} diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java index 2d7a8b2..da5484b 100644 --- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java @@ -293,11 +293,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter protected void emitName(PrintWriter writer) { if (forImplementingMethodCall) { - if (forIndirectBufferAndArrayImplementation) { - writer.print(getImplMethodName(false)); - } else { - writer.print(getImplMethodName(true)); - } + writer.print(getImplMethodName()); } else { writer.print(getName()); } @@ -348,6 +344,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter if (forDirectBufferImplementation || forIndirectBufferAndArrayImplementation) { if (type.isNIOBuffer()) { writer.print(", int " + byteOffsetArgName(i)); + if(!directNIOOnly) { + writer.print(", boolean " + isNIOArgName(i)); + } } else if (type.isNIOBufferArray()) { writer.print(", int[] " + byteOffsetArrayArgName(i)); @@ -356,6 +355,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter // Add offset argument after each primitive array if (type.isPrimitiveArray()) { + if(directNIOOnly) { + throw new RuntimeException("NIODirectOnly "+binding+" is set, but "+getArgumentName(i)+" is a primitive array"); + } writer.print(", int " + offsetArgName(i)); } } @@ -363,12 +365,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter } - protected String getImplMethodName(boolean direct) { - if (direct) { - return binding.getName() + "0"; - } else { - return binding.getName() + "1"; - } + protected String getImplMethodName() { + return binding.getName() + ( directNIOOnly ? "0" : "1" ); } protected String byteOffsetArgName(int i) { @@ -379,6 +377,14 @@ public class JavaMethodBindingEmitter extends FunctionEmitter return s + "_byte_offset"; } + protected String isNIOArgName(int i) { + return isNIOArgName(binding.getArgumentName(i)); + } + + protected String isNIOArgName(String s) { + return s + "_is_direct"; + } + protected String byteOffsetArrayArgName(int i) { return getArgumentName(i) + "_byte_offset_array"; } @@ -428,7 +434,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter protected void emitArrayLengthAndNIOBufferChecks(MethodBinding binding, PrintWriter writer) { - boolean firstBuffer = true; // Check lengths of any incoming arrays if necessary for (int i = 0; i < binding.getNumArguments(); i++) { Type type = binding.getCArgumentType(i); @@ -439,6 +444,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.println(" throw new " + getRuntimeExceptionType() + "(\"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); } else { JavaType javaType = binding.getJavaArgumentType(i); if (javaType.isNIOBuffer()) { @@ -447,29 +454,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.println(" throw new " + getRuntimeExceptionType() + "(\"Argument \\\"" + getArgumentName(i) + "\\\" was not a direct buffer\");"); } else { - if(firstBuffer) { - firstBuffer = false; - writer.print(" boolean _direct = "); - for (int j = i; j < binding.getNumArguments(); j++) { - JavaType buff = binding.getJavaArgumentType(j); - - if(buff.isNIOBuffer()) { - if(i!=j) { // not the first one - writer.println(); - writer.print(" ||"); - } - writer.print(getArgumentName(j)+" != null && BufferFactory.isDirect(" + getArgumentName(j) + ")"); - } - - } - writer.println(";"); - - } else { - writer.println(" if (" + getArgumentName(i) + " != null && _direct != BufferFactory.isDirect(" + getArgumentName(i) + "))"); - writer.println(" throw new " + getRuntimeExceptionType() + - "(\"Argument \\\"" + getArgumentName(i) + - "\\\" : Buffers passed to this method must all be either direct or indirect\");"); - } + writer.print(" boolean " + isNIOArgName(i) + " = "); + writer.println(getArgumentName(i) + " != null && BufferFactory.isDirect(" + getArgumentName(i) + ");"); } } else if (javaType.isNIOBufferArray()) { // All buffers passed down in an array of NIO buffers must be direct @@ -521,11 +507,11 @@ public class JavaMethodBindingEmitter extends FunctionEmitter } } - protected void emitCall(MethodBinding binding, PrintWriter writer, boolean direct) { - writer.print(getImplMethodName(direct)); + protected void emitCall(MethodBinding binding, PrintWriter writer) { + writer.print(getImplMethodName()); writer.print("("); - emitCallArguments(binding, writer, direct); - writer.print(")"); + emitCallArguments(binding, writer); + writer.print(");"); } @@ -550,13 +536,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter } } - if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) { - // Must generate two calls for this gated on whether the NIO - // buffers coming in are all direct or indirect - writer.println("if (_direct) {"); - writer.print (" "); - } - if (needsResultAssignment) { writer.print(" _res = "); } else { @@ -566,43 +545,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter } } - if (binding.signatureUsesJavaPrimitiveArrays() && - !binding.signatureCanUseIndirectNIO()) { - // FIXME: what happens with a C function of the form - // void foo(int* arg0, void* arg1); - // ? - - // Only one call being made in this body, going to indirect - // buffer / array entry point - emitCall(binding, writer, false); - writer.print(";"); - writer.println(); - } else { - emitCall(binding, writer, true); - writer.print(";"); - } + emitCall(binding, writer); + writer.println(); - if (binding.signatureCanUseIndirectNIO() && !directNIOOnly) { - // Must generate two calls for this gated on whether the NIO - // buffers coming in are all direct or indirect - writer.println(); - writer.println(" } else {"); - writer.print (" "); - if (needsResultAssignment) { - writer.print(" _res = "); - } else { - writer.print(" "); - if (!returnType.isVoid()) { - writer.print("return "); - } - } - emitCall(binding, writer, false); - writer.print(";"); - writer.println(); - writer.println(" }"); - } else { - writer.println(); - } emitPostCallCleanup(binding, writer); emitPrologueOrEpilogue(epilogue, writer); if (needsResultAssignment) { @@ -610,7 +555,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter } } - protected int emitCallArguments(MethodBinding binding, PrintWriter writer, boolean direct) { + protected int emitCallArguments(MethodBinding binding, PrintWriter writer) { boolean needComma = false; int numArgsEmitted = 0; @@ -643,14 +588,25 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.print("(("); } - if (type.isNIOBuffer() && !direct) { - writer.print("BufferFactory.getArray(" + getArgumentName(i) + ")"); + if (type.isNIOBuffer()) { + if(type.isNIOPointerBuffer()) { + if (directNIOOnly) { + writer.print( getArgumentName(i)+ " != null ? " + getArgumentName(i) + ".getBuffer() : null"); + } else { + writer.print( isNIOArgName(i) + " ? ( " + getArgumentName(i)+ " != null ? " + getArgumentName(i) + ".getBuffer() : null )"); + writer.print( " : BufferFactory.getArray(" + getArgumentName(i) + ")" ); + } + } else { + if (directNIOOnly) { + writer.print( getArgumentName(i) ); + } else { + writer.print( isNIOArgName(i) + " ? " + getArgumentName(i) + " : BufferFactory.getArray(" + getArgumentName(i) + ")" ); + } + } } else if (type.isArrayOfCompoundTypeWrappers()) { - writer.print(getArgumentName(i) + COMPOUND_ARRAY_SUFFIX); - } else if(type.isNIOPointerBuffer()) { - writer.print(getArgumentName(i)+"!=null?"+getArgumentName(i) + ".getBuffer():null"); + writer.print(getArgumentName(i) + COMPOUND_ARRAY_SUFFIX); } else { - writer.print(getArgumentName(i)); + writer.print(getArgumentName(i)); } if (type.isCompoundTypeWrapper()) { @@ -658,18 +614,17 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.print(getArgumentName(i)); writer.print(".getBuffer())"); } + if (type.isNIOBuffer()) { - if (direct) { - writer.print(", BufferFactory.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); + if (directNIOOnly) { + writer.print( ", BufferFactory.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); } else { - writer.print(", BufferFactory.getIndirectBufferByteOffset(" + getArgumentName(i) + ")"); + writer.print( ", " + isNIOArgName(i) + " ? BufferFactory.getDirectBufferByteOffset(" + getArgumentName(i) + ")"); + writer.print( " : BufferFactory.getIndirectBufferByteOffset(" + getArgumentName(i) + ")"); } } else if (type.isNIOBufferArray()) { writer.print(", " + byteOffsetArrayArgName(i)); - } - - // Add Array offset parameter for primitive arrays - if (type.isPrimitiveArray()) { + } else if (type.isPrimitiveArray()) { if(type.isFloatArray()) { writer.print(", BufferFactory.SIZEOF_FLOAT * "); } else if(type.isDoubleArray()) { @@ -690,6 +645,17 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.print(offsetArgName(i)); } + if (type.isNIOBuffer()) { + if (!directNIOOnly) { + writer.print( ", " + isNIOArgName(i) ); + } + } else if (type.isPrimitiveArray()) { + if (directNIOOnly) { + throw new RuntimeException("NIODirectOnly "+binding+" is set, but "+getArgumentName(i)+" is a primitive array"); + } + writer.print( ", false"); + } + needComma = true; ++numArgsEmitted; } diff --git a/src/java/com/sun/gluegen/MethodBinding.java b/src/java/com/sun/gluegen/MethodBinding.java index dae381b..5805be1 100644 --- a/src/java/com/sun/gluegen/MethodBinding.java +++ b/src/java/com/sun/gluegen/MethodBinding.java @@ -81,7 +81,7 @@ public class MethodBinding { this.containingType = bindingToCopy.containingType; this.containingCType = bindingToCopy.containingCType; this.javaReturnType = bindingToCopy.javaReturnType; - this.javaArgumentTypes = new ArrayList<JavaType>(bindingToCopy.javaArgumentTypes); + this.javaArgumentTypes = ( null != bindingToCopy.javaArgumentTypes ) ? new ArrayList<JavaType>(bindingToCopy.javaArgumentTypes) : null; this.computedSignatureProperties = bindingToCopy.computedSignatureProperties; this.argumentsUseNIO = bindingToCopy.argumentsUseNIO; this.signatureUsesNIO = bindingToCopy.signatureUsesNIO; diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java index 54263a5..b7fac1b 100755 --- a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java @@ -140,12 +140,10 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { super.emitBodyVariableDeclarations(writer); } - protected void emitBodyVariablePreCallSetup(PrintWriter writer, - boolean emittingPrimitiveArrayCritical) { - super.emitBodyVariablePreCallSetup(writer, emittingPrimitiveArrayCritical); + protected void emitBodyVariablePreCallSetup(PrintWriter writer) { + super.emitBodyVariablePreCallSetup(writer); if (callThroughProcAddress) { - if (!emittingPrimitiveArrayCritical) { // set the function pointer to the value of the passed-in procAddress FunctionSymbol cSym = getBinding().getCSymbol(); String funcPointerTypedefName = emitter.getFunctionPointerTypedefName(cSym); @@ -162,7 +160,6 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter { writer.println(") (intptr_t) procAddress;"); writer.println(" assert(" + ptrVarName + " != NULL);"); - } } } diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java index f6ae58e..2dda752 100755 --- a/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java @@ -110,8 +110,8 @@ public class ProcAddressJavaMethodBindingEmitter extends JavaMethodBindingEmitte return numEmitted; } - protected String getImplMethodName(boolean direct) { - String name = super.getImplMethodName(direct); + protected String getImplMethodName() { + String name = super.getImplMethodName(); if (callThroughProcAddress) { return ProcAddressEmitter.WRAP_PREFIX + name; } @@ -131,8 +131,8 @@ public class ProcAddressJavaMethodBindingEmitter extends JavaMethodBindingEmitte } } - protected int emitCallArguments(MethodBinding binding, PrintWriter writer, boolean indirect) { - int numEmitted = super.emitCallArguments(binding, writer, indirect); + protected int emitCallArguments(MethodBinding binding, PrintWriter writer) { + int numEmitted = super.emitCallArguments(binding, writer); if (callThroughProcAddress) { if (numEmitted > 0) { writer.print(", "); diff --git a/src/java/com/sun/gluegen/runtime/NativeLibrary.java b/src/java/com/sun/gluegen/runtime/NativeLibrary.java index c4c9f25..eb465c8 100755 --- a/src/java/com/sun/gluegen/runtime/NativeLibrary.java +++ b/src/java/com/sun/gluegen/runtime/NativeLibrary.java @@ -57,7 +57,7 @@ import java.util.*; ProcAddressTable glue code generation style without additional supporting code needed in the generated library. */ -public class NativeLibrary { +public class NativeLibrary implements DynamicLookupHelper { private static final int WINDOWS = 1; private static final int UNIX = 2; private static final int MACOSX = 3; @@ -202,10 +202,10 @@ public class NativeLibrary { } /** Looks up the given function name in this native library. */ - public long lookupFunction(String functionName) { + public long dynamicLookupFunction(String funcName) { if (libraryHandle == 0) throw new RuntimeException("Library is not open"); - return dynLink.lookupSymbol(libraryHandle, functionName); + return dynLink.lookupSymbol(libraryHandle, funcName); } /** Retrieves the low-level library handle from this NativeLibrary |