From 3ed3e9887c459169b807165c9df2ae2bc2990a31 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Thu, 6 Jul 2023 10:35:30 +0200
Subject: GlueGen JavaCallback: Remove ambiguity: Config
 JavaCallbackDef/JavaCallbackKey: Always define both parameter indices;
 emitJavaStaticCallback(): Use cbFuncBinding and cbFuncKeyIndices from
 callback parameter to build key

---
 .../com/jogamp/gluegen/JavaCallbackEmitter.java    |   8 +-
 src/java/com/jogamp/gluegen/JavaConfiguration.java | 110 +++++++++++++--------
 src/java/com/jogamp/gluegen/JavaEmitter.java       |  26 ++---
 3 files changed, 78 insertions(+), 66 deletions(-)

(limited to 'src/java/com')

diff --git a/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java b/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
index 1b6aa05..e4046ac 100644
--- a/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaCallbackEmitter.java
@@ -453,14 +453,10 @@ public final class JavaCallbackEmitter {
         if( mapNativePtrToCompound[0] ) {
             unit.emitln("    final "+origUserParamJType[0]+" "+info.cbFuncUserParamName+" = "+origUserParamJType[0]+".derefPointer(nativeUserParamPtr);");
         }
-        if( useDataMap ) {
-            unit.emitln("    final "+DataClassName+" value;");
-        } else {
-            unit.emitln("    final "+DataClassName+" value;");
-        }
+        unit.emitln("    final "+DataClassName+" value;");
         unit.emitln("    synchronized( "+lockInstanceName+" ) {");
         if( useDataMap ) {
-            unit.emitln("      final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), info.setFuncKeyIndices, false).toString()+");");
+            unit.emitln("      final "+KeyClassName+" key = new "+KeyClassName+"("+info.cbFuncBinding.getJavaCallSelectArguments(new StringBuilder(), info.cbFuncKeyIndices, false).toString()+");");
             unit.emitln("      value = "+dataMapInstanceName+".get(key);");
         } else {
             unit.emitln("      value = "+dataInstanceName+";");
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java
index 5cea4c3..e530e0c 100644
--- a/src/java/com/jogamp/gluegen/JavaConfiguration.java
+++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java
@@ -190,9 +190,10 @@ public class JavaConfiguration {
       final String cbFuncTypeName;
       final int cbFuncUserParamIdx;
       final String setFuncName;
-      final List<Integer> setFuncKeyIndices = new ArrayList<Integer>();
       final int setFuncUserParamIdx; // optional
+      final List<Integer> cbFuncKeyIndices = new ArrayList<Integer>();
       final String setFuncKeyClassName; // optional
+      final List<Integer> setFuncKeyIndices = new ArrayList<Integer>();
       JavaCallbackDef(final String cbFuncTypeName, final int cbFuncUserParamIdx, final String setFuncName, final int setFuncUserParamIdx, final String setFuncKeyClassName) {
           this.cbFuncTypeName = cbFuncTypeName;
           this.cbFuncUserParamIdx = cbFuncUserParamIdx;
@@ -202,8 +203,8 @@ public class JavaConfiguration {
       }
       @Override
       public String toString() {
-          return String.format("JavaCallbackDef[cbFunc[type %s, userParamIdx %d], set[%s, keys %s, userParamIdx %d, KeyClass %s]]",
-                  cbFuncTypeName, cbFuncUserParamIdx, setFuncName, setFuncKeyIndices.toString(), setFuncUserParamIdx, setFuncKeyClassName);
+          return String.format("JavaCallbackDef[cbFunc[type %s, userParamIdx %d, keys %s], set[%s, keys %s, userParamIdx %d, KeyClass %s]]",
+                  cbFuncTypeName, cbFuncUserParamIdx, cbFuncKeyIndices.toString(), setFuncName, setFuncKeyIndices.toString(), setFuncUserParamIdx, setFuncKeyClassName);
       }
     }
     private final List<JavaCallbackDef> javaCallbackList = new ArrayList<JavaCallbackDef>();
@@ -1692,26 +1693,9 @@ public class JavaConfiguration {
   protected void readJavaCallbackDef(final StringTokenizer tok, final String filename, final int lineNo) {
     try {
       final String setFuncName = tok.nextToken();
-      final int setFuncUserParamIdx;
-      final String cbFuncTypeName;
-      {
-          final String stok = tok.nextToken();
-          int ival = -1;
-          String sval = null;
-          try {
-              ival = Integer.valueOf(stok);
-          } catch(final NumberFormatException nfe) {
-              sval = stok;
-          }
-          if( null == sval ) {
-              setFuncUserParamIdx = ival;
-              cbFuncTypeName = tok.nextToken();
-          } else {
-              setFuncUserParamIdx = -1;
-              cbFuncTypeName = sval;
-          }
-      }
-      final Integer cbFuncUserParamIdx = Integer.valueOf(tok.nextToken());
+      final int setFuncUserParamIdx = Integer.parseInt(tok.nextToken());
+      final String cbFuncTypeName = tok.nextToken();
+      final int cbFuncUserParamIdx = Integer.parseInt(tok.nextToken());
       final String cbFuncKeyClassName;
       if( tok.hasMoreTokens() ) {
           cbFuncKeyClassName = tok.nextToken();
@@ -1734,18 +1718,54 @@ public class JavaConfiguration {
       if( null == jcd ) {
           throw new IllegalArgumentException("JavaCallbackDef '"+setFuncName+"\' not (yet) defined.");
       }
+
+      // Collect setFuncKeyIndices
+      String stok = null;
       while( tok.hasMoreTokens() ) {
-          final int idx = Integer.valueOf(tok.nextToken());
+          stok = tok.nextToken();
+          if( !isInteger(stok) ) {
+              break;
+          }
+          final int idx = Integer.parseInt(stok);
           if( 0 > idx ) {
-              throw new IllegalArgumentException("JavaCallbackKey '"+setFuncName+"\' index "+idx+" not in range [0..n].");
+              throw new IllegalArgumentException("JavaCallbackKey '"+setFuncName+"\' SetCallback-ParamIndex "+idx+" not in range [0..n].");
           }
           jcd.setFuncKeyIndices.add( idx );
       }
+
+      // Validate proper CallbackFuncType
+      if( null == stok ) {
+          throw new IllegalArgumentException("JavaCallbackKey '"+setFuncName+"\': CallbackFuncType missing.");
+      }
+      if( !stok.equals(jcd.cbFuncTypeName) ) {
+          throw new IllegalArgumentException("JavaCallbackKey '"+setFuncName+"\': CallbackFuncType '"+stok+"' not matching JavaCallbackDef: "+jcd);
+      }
+
+      // Collect cbFuncKeyIndices
+      while( tok.hasMoreTokens() ) {
+          final int idx = Integer.parseInt(tok.nextToken());
+          if( 0 > idx ) {
+              throw new IllegalArgumentException("JavaCallbackKey '"+setFuncName+"\' CallbackFunc-ParamIndex "+idx+" not in range [0..n].");
+          }
+          jcd.cbFuncKeyIndices.add( idx );
+      }
+      if( jcd.setFuncKeyIndices.size() != jcd.cbFuncKeyIndices.size() ) {
+          throw new IllegalArgumentException("JavaCallbackKey '"+setFuncName+"\' SetCallback-ParamIndex list count "+jcd.setFuncKeyIndices.toString()+
+                                             " != CallbackFunc-ParamIndex count "+jcd.cbFuncKeyIndices.toString());
+      }
     } catch (final NoSuchElementException e) {
       throw new RuntimeException("Error parsing \"JavaCallbackKey\" command at line " + lineNo +
         " in file \"" + filename + "\"", e);
     }
   }
+  private static boolean isInteger(final String s) {
+      try {
+          Integer.parseInt(s);
+          return true;
+      } catch(final Exception e) {
+          return false;
+      }
+  }
 
   protected void readExtendedIntfImplSymbols(final StringTokenizer tok, final String filename, final int lineNo, final boolean forInterface, final boolean forImplementation, final boolean onlyList) {
     File javaFile;
@@ -2381,6 +2401,7 @@ public class JavaConfiguration {
       final String staticCBMethodSignature;
       final FunctionType cbFuncType;
       final MethodBinding cbFuncBinding;
+      final List<Integer> cbFuncKeyIndices;
       final int cbFuncUserParamIdx;
       final String cbFuncUserParamName;
       final Type cbFuncUserParamType;
@@ -2388,13 +2409,13 @@ public class JavaConfiguration {
       final String setFuncName;
       final List<Integer> setFuncKeyIndices;
       final String setFuncKeyClassName;
+      final int setFuncUserParamIdx;
       boolean setFuncProcessed;
       int setFuncCBParamIdx;
-      int setFuncUserParamIdx;
       boolean keyClassEmitted;
 
       public JavaCallbackInfo(final String cbFuncTypeName, final String cbSimpleClazzName, final String cbFQClazzName, final String staticCBMethodSignature,
-                              final FunctionType cbFuncType, final MethodBinding cbFuncBinding, final int cbFuncUserParamIdx,
+                              final FunctionType cbFuncType, final MethodBinding cbFuncBinding, final int cbFuncUserParamIdx, final List<Integer> cbFuncKeyIndices,
                               final String setFuncName, final int setFuncUserParamIdx, final List<Integer> setFuncKeyIndices, final String setFuncKeyClassName) {
           this.cbFuncTypeName = cbFuncTypeName;
           this.cbSimpleClazzName = cbSimpleClazzName;
@@ -2416,42 +2437,51 @@ public class JavaConfiguration {
                   }
               }
               this.cbFuncUserParamIdx = paramIdx;
+              this.cbFuncKeyIndices = cbFuncKeyIndices;
               this.cbFuncUserParamName = paramName;
               this.cbFuncUserParamType = paramType;
           }
           this.setFuncName = setFuncName;
           this.setFuncKeyIndices = setFuncKeyIndices;
           this.setFuncKeyClassName = setFuncKeyClassName;
+          this.setFuncUserParamIdx = setFuncUserParamIdx;
           this.setFuncProcessed = false;
           this.setFuncCBParamIdx = -1;
-          this.setFuncUserParamIdx = setFuncUserParamIdx;
           this.keyClassEmitted = false;
       }
+      private void validateKeyIndices(final FunctionType setFuncType) {
+          if( this.cbFuncKeyIndices.size() != this.setFuncKeyIndices.size() ) {
+              throw new IllegalArgumentException("JavaCallback "+setFuncName+": Key count mismatch: setFunc "+setFuncKeyIndices.toString()+
+                      " != cbFunc "+cbFuncKeyIndices.toString());
+          }
+          for(int i=0; i< this.cbFuncKeyIndices.size(); ++i) {
+              final int cbFuncIdx = this.cbFuncKeyIndices.get(i);
+              final Type t1 = this.cbFuncType.getArgumentType(cbFuncIdx);
+              final int setFuncIdx = this.setFuncKeyIndices.get(i);
+              final Type t2 = setFuncType.getArgumentType(setFuncIdx);
+              if( !t1.equals(t2) ) {
+                  throw new IllegalArgumentException("JavaCallback "+setFuncName+": Key Type mismatch: setFunc#"+setFuncIdx+" with "+t2.toString()+", cbFunc#"+cbFuncIdx+" with "+t1.toString());
+              }
+          }
+      }
 
-      public void setFuncProcessed(final int cbParamIdx, final int userParamIdx) {
+      public void setFuncProcessed(final FunctionType setFuncType, final int cbParamIdx) {
         if( !setFuncProcessed ) {
-            if( 0 <= cbParamIdx && 0 <= userParamIdx ) {
+            if( 0 <= cbParamIdx ) {
                 setFuncProcessed = true;
                 setFuncCBParamIdx = cbParamIdx;
-                if( 0 <= setFuncUserParamIdx ) {
-                    if( setFuncUserParamIdx != userParamIdx ) {
-                        throw new IllegalArgumentException("Mismatch pre-set setFuncUserParamIdx "+setFuncUserParamIdx+", given "+userParamIdx+": "+toString());
-                    }
-                } else {
-                    setFuncUserParamIdx = userParamIdx;
-                }
+                validateKeyIndices(setFuncType);
             } else {
                 setFuncCBParamIdx = -1;
-                setFuncUserParamIdx = -1;
             }
         }
       }
 
       @Override
       public String toString() {
-          return String.format("JavaCallbackInfo[cbFunc[%s%s, userParam[idx %d, '%s', %s], set[%s(ok %b, cbIdx %d, upIdx %d, keys %s, KeyClass '%s'], %s]",
+          return String.format("JavaCallbackInfo[cbFunc[%s%s, userParam[idx %d, '%s', %s, keys %s], set[%s(ok %b, cbIdx %d, upIdx %d, keys %s, KeyClass '%s'], %s]",
                   cbFuncTypeName, staticCBMethodSignature,
-                  cbFuncUserParamIdx, cbFuncUserParamName, cbFuncUserParamType.getSignature(null).toString(),
+                  cbFuncUserParamIdx, cbFuncUserParamName, cbFuncUserParamType.getSignature(null).toString(), cbFuncKeyIndices.toString(),
                   setFuncName, setFuncProcessed, setFuncCBParamIdx, setFuncUserParamIdx,
                   setFuncKeyIndices.toString(), setFuncKeyClassName,
                   cbFuncType.toString(cbFuncTypeName, false, true));
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 8af79e4..07bd55d 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -1473,7 +1473,7 @@ public class JavaEmitter implements GlueEmitter {
                       funcType.toString(jcbd.cbFuncTypeName, false, true));
           }
           final JavaCallbackInfo jcbi1 = new JavaCallbackInfo(jcbd.cbFuncTypeName, cbSimpleClazzName, cbFQClazzName, jcbi0.staticCBMethodSignature,
-                                                              funcType, jcbi0.cbFuncBinding, jcbi0.cbFuncUserParamIdx,
+                                                              funcType, jcbi0.cbFuncBinding, jcbi0.cbFuncUserParamIdx, jcbi0.cbFuncKeyIndices,
                                                               jcbd.setFuncName, jcbd.setFuncUserParamIdx, jcbd.setFuncKeyIndices, jcbd.setFuncKeyClassName);
           cfg.setFuncToJavaCallbackMap.put(jcbd.setFuncName, jcbi1);
           LOG.log(INFO, "JavaCallbackInfo: Reusing {0} -> {1}", jcbd.setFuncName, jcbi0);
@@ -1493,7 +1493,7 @@ public class JavaEmitter implements GlueEmitter {
                       cbFuncBinding.getJavaReturnType()+", func "+funcType.toString(jcbd.cbFuncTypeName, false, true));
           }
           final JavaCallbackInfo jcbi1 = new JavaCallbackInfo(jcbd.cbFuncTypeName, cbSimpleClazzName, cbFQClazzName, cbMethodSignature.toString(),
-                                                              funcType, cbFuncBinding, jcbd.cbFuncUserParamIdx,
+                                                              funcType, cbFuncBinding, jcbd.cbFuncUserParamIdx, jcbd.cbFuncKeyIndices,
                                                               jcbd.setFuncName, jcbd.setFuncUserParamIdx, jcbd.setFuncKeyIndices, jcbd.setFuncKeyClassName);
           cfg.setFuncToJavaCallbackMap.put(jcbd.setFuncName, jcbi1);
           javaCallbackInterfaceMap.put(cbFQClazzName, jcbi1);
@@ -3104,7 +3104,7 @@ public class JavaEmitter implements GlueEmitter {
         stringArgIndices = PascalStringIdx.pushValueIndex(pascalStringArgs, stringArgIndices);
     }
     final JavaCallbackInfo jcbi = cfg.setFuncToJavaCallbackMap.get( sym.getName() );
-    int jcbiSetFuncCBParamIdx=-1, jcbiSetFuncUserParamIdx=-1;
+    int jcbiSetFuncCBParamIdx=-1;
 
     for (int i = 0; i < sym.getNumArguments(); i++) {
       final Type cArgType = sym.getArgumentType(i);
@@ -3121,20 +3121,6 @@ public class JavaEmitter implements GlueEmitter {
           mappedType = JavaType.createForNamedClass( jcbi.cbFQClazzName );
       } else if( null != jcbi && i == jcbi.setFuncUserParamIdx && cArgType.isPointer() ) {
           // Replace userParam argument '<userParamType>*' if 'void*' with Object
-          jcbiSetFuncUserParamIdx=i;
-          if( cArgType.getTargetType().isVoid() ) {
-              if( jcbi.cbFuncUserParamType.isCompound() ) {
-                  mappedType = JavaType.createForClass(long.class);
-              } else {
-                  mappedType = JavaType.forObjectClass();
-              }
-          }
-      } else if( null != jcbi && jcbi.cbFuncUserParamName.equals( cArgName ) &&
-                 ( !jcbi.setFuncProcessed || i == jcbi.setFuncUserParamIdx ) &&
-                 cArgType.isPointer() && jcbi.cbFuncUserParamType.equals( cArgType.getTargetType() ) )
-      {
-          // Replace userParam argument '<userParamType>*' if 'void*' with Object
-          jcbiSetFuncUserParamIdx=i;
           if( cArgType.getTargetType().isVoid() ) {
               if( jcbi.cbFuncUserParamType.isCompound() ) {
                   mappedType = JavaType.createForClass(long.class);
@@ -3174,9 +3160,9 @@ public class JavaEmitter implements GlueEmitter {
       //System.out.println("During binding of [" + sym + "], added mapping from C type: " + cArgType + " to Java type: " + mappedType);
     }
     if( null != jcbi ) {
-        jcbi.setFuncProcessed(jcbiSetFuncCBParamIdx, jcbiSetFuncUserParamIdx);
-        LOG.log(INFO, "BindFunc.JavaCallback: {0}: set[cbParamIdx {1}, userParamIdx {2}], {3}, {4}",
-                sym.getName(), jcbiSetFuncCBParamIdx, jcbiSetFuncUserParamIdx, sym.getType().toString(sym.getName(), false, true), jcbi);
+        jcbi.setFuncProcessed(sym.getType(), jcbiSetFuncCBParamIdx);
+        LOG.log(INFO, "BindFunc.JavaCallback: {0}: set[cbParamIdx {1}], {3}, {4}",
+                sym.getName(), jcbiSetFuncCBParamIdx, sym.getType().toString(sym.getName(), false, true), jcbi);
     }
     final MethodBinding mb = new MethodBinding(sym, delegationImplName,
                                                javaReturnType, javaArgumentTypes,
-- 
cgit v1.2.3