From 040e730115f8a50b598edb448fc29f8917bde392 Mon Sep 17 00:00:00 2001
From: Kenneth Russel <kbrussel@alum.mit.edu>
Date: Mon, 26 May 2008 18:35:33 +0000
Subject: Added support for passing outgoing arrays of compound types,
 including non-const arrays of compound types and the associated copies back
 to Java, in support of constructs like eglChooseConfig. Generated code has
 been compiled but not yet tested. Refactorings to allow generated glue code
 using StructAccessors to work on Java ME / CDC / FP + JSR-239 NIO, as well as
 Java SE. Bug fix to ForceProcAddressGen.

git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/gluegen/trunk@77 a78bb65f-1512-4460-ba86-f6dc96a7bf27
---
 .../com/sun/gluegen/JavaMethodBindingEmitter.java  | 80 ++++++++++++++++++++--
 1 file changed, 73 insertions(+), 7 deletions(-)

(limited to 'src/java/com/sun/gluegen/JavaMethodBindingEmitter.java')

diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
index 8629371..528a0cb 100644
--- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
@@ -88,6 +88,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
   // number of elements of the returned array.
   private String returnedArrayLengthExpression;
 
+  // A suffix used to create a temporary outgoing array of Buffers to
+  // represent an array of compound type wrappers
+  private static final String COMPOUND_ARRAY_SUFFIX = "_buf_array_copy";
+
   public JavaMethodBindingEmitter(MethodBinding binding,
                                   PrintWriter output,
                                   String runtimeExceptionType,
@@ -231,9 +235,20 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
         // Compound type wrappers are unwrapped to ByteBuffer
         return "java.nio.ByteBuffer";
       } else if (type.isArrayOfCompoundTypeWrappers()) {
-        return "java.nio.ByteBuffer";
+        if (skipBuffers) {
+          return "java.nio.ByteBuffer";
+        } else {
+          // In the case where this is called with a false skipBuffers
+          // argument we want to erase the array of compound type
+          // wrappers to ByteBuffer[]
+          return "java.nio.ByteBuffer[]";
+        }
       }
     }
+    if (type.isArrayOfCompoundTypeWrappers()) {
+      // We don't want to bake the array specification into the type name
+      return type.getName() + "[]";
+    }
     return type.getName();
   }
 
@@ -385,6 +400,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
 
   protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) {
     emitArrayLengthAndNIOBufferChecks(binding, writer);
+    emitCompoundArrayCopies(binding, writer);
   }
 
   protected void emitArrayLengthAndNIOBufferChecks(MethodBinding binding, PrintWriter writer) {
@@ -448,6 +464,26 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
     }
   }
 
+  protected void emitCompoundArrayCopies(MethodBinding binding, PrintWriter writer) {
+    // If the method binding uses outgoing arrays of compound type
+    // wrappers, we need to generate a temporary copy of this array
+    // into a ByteBuffer[] for processing by the native code
+    if (binding.signatureUsesArraysOfCompoundTypeWrappers()) {
+      for (int i = 0; i < binding.getNumArguments(); i++) {
+        JavaType javaType = binding.getJavaArgumentType(i);
+        if (javaType.isArrayOfCompoundTypeWrappers()) {
+          String argName = getArgumentName(i);
+          String tempArrayName = argName + COMPOUND_ARRAY_SUFFIX;
+          writer.println("    ByteBuffer[] " + tempArrayName + " = new ByteBuffer[" + argName + ".length];");
+          writer.println("    for (int _ctr = 0; _ctr < + " + argName + ".length; _ctr++) {");
+          writer.println("      " + javaType.getName() + " _tmp = " + argName + "[_ctr];");
+          writer.println("      " + tempArrayName + "[_ctr] = ((_tmp == null) ? null : _tmp.getBuffer());");
+          writer.println("    }");
+        }
+      }
+    }
+  }
+
   protected void emitCall(MethodBinding binding, PrintWriter writer, boolean direct) {
     writer.print(getImplMethodName(direct));
     writer.print("(");
@@ -469,7 +505,8 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
       } else if (returnType.isArrayOfCompoundTypeWrappers()) {
         writer.println("java.nio.ByteBuffer[] _res;");
         needsResultAssignment = true;
-      } else if ((epilogue != null) && (epilogue.size() > 0)) {
+      } else if (((epilogue != null) && (epilogue.size() > 0)) ||
+                 binding.signatureUsesArraysOfCompoundTypeWrappers()) {
         emitReturnType(writer);
         writer.println(" _res;");
         needsResultAssignment = true;
@@ -529,6 +566,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
     } else {
       writer.println();
     }
+    emitPostCallCleanup(binding, writer);
     emitPrologueOrEpilogue(epilogue, writer);
     if (needsResultAssignment) {
       emitCallResultReturn(binding, writer);
@@ -569,9 +607,11 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
       }
 
       if (type.isNIOBuffer() && !direct) {
-         writer.print("BufferFactory.getArray(" + getArgumentName(i) + ")");
+        writer.print("BufferFactory.getArray(" + getArgumentName(i) + ")");
+      } else if (type.isArrayOfCompoundTypeWrappers()) {
+        writer.print(getArgumentName(i) + COMPOUND_ARRAY_SUFFIX);
       } else {
-         writer.print(getArgumentName(i));
+        writer.print(getArgumentName(i));
       }
 
       if (type.isCompoundTypeWrapper()) {
@@ -617,6 +657,32 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
     return numArgsEmitted;
   }
 
+  protected void emitPostCallCleanup(MethodBinding binding, PrintWriter writer) {
+    if (binding.signatureUsesArraysOfCompoundTypeWrappers()) {
+      // For each such array, we need to take the ByteBuffer[] that
+      // came back from the C method invocation and wrap the
+      // ByteBuffers back into the wrapper types
+      for (int i = 0; i < binding.getNumArguments(); i++) {
+        JavaType javaArgType = binding.getJavaArgumentType(i);
+        if (javaArgType.isArrayOfCompoundTypeWrappers()) {
+          String argName = binding.getArgumentName(i);
+          writer.println("    for (int _ctr = 0; _ctr < " + argName + ".length; _ctr++) {");
+          writer.println("      if ((" + argName + "[_ctr] == null && " + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr] == null) ||");
+          writer.println("          (" + argName + "[_ctr] != null && " + argName + "[_ctr].getBuffer() == " + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr])) {");
+          writer.println("        // No copy back needed");
+          writer.println("      } else {");
+          writer.println("        if (" + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr] == null) {");
+          writer.println("          " + argName + "[_ctr] = null;");
+          writer.println("        } else {");
+          writer.println("          " + argName + "[_ctr] = " + javaArgType.getName() + ".create(" + argName + COMPOUND_ARRAY_SUFFIX + "[_ctr]);");
+          writer.println("        }");
+          writer.println("      }");
+          writer.println("    }");
+        }
+      }
+    }
+  }
+
   protected void emitCallResultReturn(MethodBinding binding, PrintWriter writer) {
     JavaType returnType = binding.getJavaReturnType();
 
@@ -624,9 +690,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
       String fmt = getReturnedArrayLengthExpression();
       writer.println("    if (_res == null) return null;");
       if (fmt == null) {
-        writer.print("    return " + returnType.getName() + ".create(_res.order(java.nio.ByteOrder.nativeOrder()))");
+        writer.print("    return " + returnType.getName() + ".create(BufferFactory.nativeOrder(_res))");
       } else {
-        writer.println("    _res.order(java.nio.ByteOrder.nativeOrder());");
+        writer.println("    BufferFactory.nativeOrder(_res);");
         String expr = new MessageFormat(fmt).format(argumentNameArray());
         PointerType cReturnTypePointer = binding.getCReturnType().asPointer();
         CompoundType cReturnType = null;
@@ -645,7 +711,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
         writer.println("      _res.position(_count * " + getReturnTypeString(true) + ".size());");
         writer.println("      _res.limit   ((1 + _count) * " + getReturnTypeString(true) + ".size());");
         writer.println("      java.nio.ByteBuffer _tmp = _res.slice();");
-        writer.println("      _tmp.order(java.nio.ByteOrder.nativeOrder());");
+        writer.println("      BufferFactory.nativeOrder(_tmp);");
         writer.println("      _res.position(0);");
         writer.println("      _res.limit(_res.capacity());");
         writer.println("      _retarray[_count] = " + getReturnTypeString(true) + ".create(_tmp);");
-- 
cgit v1.2.3