gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r2967 - in freeway: native src/org/gnu/freeway/cwrappers/ut


From: mdonoughe
Subject: [GNUnet-SVN] r2967 - in freeway: native src/org/gnu/freeway/cwrappers/util
Date: Wed, 7 Jun 2006 16:58:43 -0700 (PDT)

Author: mdonoughe
Date: 2006-06-07 16:58:36 -0700 (Wed, 07 Jun 2006)
New Revision: 2967

Added:
   freeway/native/switch-table.c
   freeway/native/switch-table.h
Modified:
   freeway/native/org_gnu_freeway_server_CPluginLoader.c
   freeway/src/org/gnu/freeway/cwrappers/util/CWrapper.java
   freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java
Log:
SwitchTableGenerator now generates switch-tables. New functions in
org_gnu_freeway_server_CPluginLoader.c to fulfill some requirements from
switch-table.c. This code should compile, but I haven't tested out the script
that moves things to the PC yet, so I haven't tried it. There are known issues
with the functions that convert between pointers and objects.


Modified: freeway/native/org_gnu_freeway_server_CPluginLoader.c
===================================================================
--- freeway/native/org_gnu_freeway_server_CPluginLoader.c       2006-06-07 
21:16:47 UTC (rev 2966)
+++ freeway/native/org_gnu_freeway_server_CPluginLoader.c       2006-06-07 
23:58:36 UTC (rev 2967)
@@ -75,6 +75,105 @@
   return (*env)->CallIntMethod(env, input, method);
 }
 
+static jobject convIntToCInt(int input, JNIEnv * env) {
+fprintf(stderr, "in convIntToCInt\n");
+  jclass classCInt;
+  jmethodID method;
+
+  classCInt = (*env)->FindClass(env, "org/gnu/freeway/cwrappers/CInt");
+  if(classCInt == NULL)
+    return 0;
+  method = (*env)->GetMethodID(env, classCInt, "<init>", "(I)V");
+  if(method == NULL)
+    return 0;
+fprintf(stderr, "leaving convIntToCInt\n");
+  return (*env)->NewObject(env, classCInt, method, input);
+}
+
+static long convCLongToLong(jobject input, JNIEnv * env) {
+fprintf(stderr, "in convCLongToLong\n");
+  jclass classCLong;
+  jmethodID method;
+
+  if(input == NULL)
+    return 0;
+  classCInt = (*env)->FindClass(env, "org/gnu/freeway/cwrappers/CLong");
+  if(classCLong == NULL)
+    return 0;
+  method = (*env)->GetMethodID(env, classCLong, "getValue", "()J");
+  if(method == NULL)
+    return 0;
+fprintf(stderr, "leaving convCLongToLong\n");
+  return (*env)->CallLongMethod(env, input, method);
+}
+
+static jobject convLongToCLong(long input, JNIEnv * env) {
+fprintf(stderr, "in convLongToCLong\n");
+  jclass classCLong;
+  jmethodID method;
+
+  classCInt = (*env)->FindClass(env, "org/gnu/freeway/cwrappers/CLong");
+  if(classCLong == NULL)
+    return 0;
+  method = (*env)->GetMethodID(env, classCLong, "<init>", "(J)V");
+  if(method == NULL)
+    return 0;
+fprintf(stderr, "leaving convLongToCLong\n");
+  return (*env)->NewObject(env, classCLong, method, input);
+}
+
+static void * convObjectToPtr(jobject input, JNIEnv * env) {
+fprintf(stderr, "in convObjectToPtr\n");
+  jclass objectClass;
+  jmethodID method;
+  jobject jByteArray;
+  
+  if(input == NULL)
+       return NULL;
+  objectClass = (*env)->GetObjectClass(env, input);
+  if(objectClass == NULL)
+       return NULL;
+  method = (*env)->GetMethodID(env, objectClass, "serializeToByteArray", 
"()[B");
+  if(method == NULL)
+       return NULL;
+  jByteArray = (*env)->CallObjectMethod(env, input, method);
+fprintf(stderr, "leaving convObjectToPtr\n");
+  return (void *) (*env)->GetByteArrayElements(env, jByteArray, NULL);
+}
+//FIXME: there is a leak here. array cannot be released
+//FIXME: this will not work because we don't know the length of the array
+static jobject convPtrToNewObject(void * input, jclass returnType, JNIEnv * 
env) {
+fprintf(stderr, "in convPtrToObject\n");
+  jmethodID method;
+  
+  if(input == NULL)
+       return NULL;
+  method = (*env)->GetMethodID(env, returnType, "<init>", "([B)V");
+  if(method == NULL)
+       return NULL;
+fprintf(stderr, "leaving convPtrToObject\n");
+  return (*env)->NewObject(env, input, method);
+}
+//FIXME:leak, doesn't work, see above
+static void updateObjectFromPtr(void * input, jobject target, JNIEnv * env) {
+//better to quit while you're ahead here for the sake of testing. This is 
likely to cause a VM crash. quiting here may be the correct thing to do in most 
cases.
+return;
+fprintf(stderr, "in updateObjectFromPtr\n");
+  jclass objectClass;
+  jmethodID method;
+  
+  if(input == NULL)
+       return NULL;
+  objectClass = (*env)->GetObjectClass(env, input);
+  if(objectClass == NULL)
+       return NULL;
+  method = (*env)->GetMethodID(env, objectClass, "deserializeFromByteArray", 
"([B)V");
+  if(method == NULL)
+       return NULL;
+  jByteArray = (*env)->CallObjectMethod(env, target, method, input);
+fprintf(stderr, "leaving updateObjectFromPtr\n");
+}
+
 static jobject convJStringToCString(jstring input, JNIEnv * env) {
 fprintf(stderr, "in convJStringToCString\n");
   jclass classCString;
@@ -262,9 +361,7 @@
   m->jcapi = capi; // FIXME: add extra argument!
   PTHREAD_GET_SELF(&m->thread);
 
-#if 0
 #include "switch-table.c"
-#endif
 #if 0
   /* here is the idea of what the generated code should look like: */
   switch (functionType) { 

Added: freeway/native/switch-table.c
===================================================================
--- freeway/native/switch-table.c       2006-06-07 21:16:47 UTC (rev 2966)
+++ freeway/native/switch-table.c       2006-06-07 23:58:36 UTC (rev 2967)
@@ -0,0 +1,30 @@
+// This file was autogenerated by SwitchTableGenerator
+jobject * jargs = (*env)->GetObjectArrayElements(env, arguments, NULL);
+if(jargs == NULL)
+  return NULL;
+switch (functionType) {
+  case 13: {
+    void * carg0 = convObjectToPtr(jargs[0], env);
+    int cret = ((FunctionType13) 
((void**)m->modulePtr)[functionOffset])(carg0);
+    updateObjectFromPtr(jargs[0], carg0, env);
+    oret = convIntToCInt(cret, env);
+  }
+  case 60: {
+    int carg0 = convCIntToInt(jargs[0], env);
+    long long carg1 = convCLongToLong(jargs[1], env);
+    ((FunctionType60) ((void**)m->modulePtr)[functionOffset])(carg0, carg1);
+  }
+  case 42: {
+    int carg0 = convCIntToInt(jargs[0], env);
+    int carg1 = convCIntToInt(jargs[1], env);
+    ((FunctionType42) ((void**)m->modulePtr)[functionOffset])(carg0, carg1);
+  }
+  case 10: {
+    int carg0 = convCIntToInt(jargs[0], env);
+    long long cret = ((FunctionType10) 
((void**)m->modulePtr)[functionOffset])(carg0);
+    oret = convLongToCLong(cret, env);
+  }
+  default:
+    assert(0);
+}
+(*env)->ReleaseObjectArrayElements(env, arguments, jargs, 0);

Added: freeway/native/switch-table.h
===================================================================
--- freeway/native/switch-table.h       2006-06-07 21:16:47 UTC (rev 2966)
+++ freeway/native/switch-table.h       2006-06-07 23:58:36 UTC (rev 2967)
@@ -0,0 +1,5 @@
+// This file was autogenerated by SwitchTableGenerator
+typedef int (FunctionType13*)(void * arg0);
+typedef void (FunctionType60*)(int arg0, long long arg1);
+typedef void (FunctionType42*)(int arg0, int arg1);
+typedef long long (FunctionType10*)(int arg0);

Modified: freeway/src/org/gnu/freeway/cwrappers/util/CWrapper.java
===================================================================
--- freeway/src/org/gnu/freeway/cwrappers/util/CWrapper.java    2006-06-07 
21:16:47 UTC (rev 2966)
+++ freeway/src/org/gnu/freeway/cwrappers/util/CWrapper.java    2006-06-07 
23:58:36 UTC (rev 2967)
@@ -35,12 +35,16 @@
         * kind of C calling convention that applies.
         */
        public static final int MAX_KIND = 6;
-       public static final int INT_KIND = 0;
-       public static final int PTR_KIND = 1;
-       public static final int FLT_KIND = 2;
-       public static final int LINT_KIND = 3;
-       public static final int DBLE_KIND = 4;
-       public static final int VOID_KIND = MAX_KIND;
+       //can't use 0 for arguments because 01 yeilds the same function type as 
1
+       public static final int INT_KIND = 1;
+       public static final int PTR_KIND = 2;
+       public static final int FLT_KIND = 3;
+       public static final int LINT_KIND = 4;
+       public static final int DBLE_KIND = 5;
+       //void can only exist where a 0 makes a difference
+       public static final int VOID_KIND = 0;
        
+       public static final String[] CTYPES = {"void", "int", "void *", 
"float", "long long", "double"};
+       
        public void deserializeFromByteArray(byte[] serializedData);
 }

Modified: freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java
===================================================================
--- freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java        
2006-06-07 21:16:47 UTC (rev 2966)
+++ freeway/src/org/gnu/freeway/cwrappers/util/SwitchTableGenerator.java        
2006-06-07 23:58:36 UTC (rev 2967)
@@ -31,6 +31,7 @@
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.io.Writer;
+import java.util.HashSet;
 
 /**
  * @file SwitchTableGenerator.java
@@ -59,8 +60,11 @@
                StringBuffer clsPrefix = new StringBuffer();
                StringBuffer srcPrefix = new StringBuffer();
                StringBuffer natPrefix = new StringBuffer();
+               HashSet functionTypeSet = new HashSet();
                
                int i;
+               
+               //parse arguments
                StringBuffer currentArg = null;
                for(i = 0; i < args.length; i++)
                        if(args[i].startsWith("-"))
@@ -80,12 +84,14 @@
                                currentArg = null;
                        } else
                                break;
+               //use defaults
                if(clsPrefix.length() == 0)
                        clsPrefix.append("build");
                if(srcPrefix.length() == 0)
                        srcPrefix.append("src");
                if(natPrefix.length() == 0)
                        natPrefix.append("native");
+               //aborted argument parsing, or the last argument was incomplete
                if(i < args.length || currentArg != null) {
                        System.err.println("SwitchTableGenerator");
                        System.err.println("a source code generator for 
Freeway");
@@ -109,6 +115,7 @@
                File sourcesDir = new File(srcPrefix + servicesSubpath + 
File.separator + "impl");
                File nativeCDir = new File(natPrefix.toString());
                
+               //create sources folder
                if(!sourcesDir.exists())
                        if(!sourcesDir.mkdirs()) {
                                try {
@@ -118,9 +125,10 @@
                                }
                        }
                
+               //process every class
                File inputClasses[] = classesDir.listFiles(new 
ClassFilesFilter());
-               
                for(i = 0; i < inputClasses.length; i++) {
+                       //get a Class instance
                        Class inputClass = null;
                        try {
                                inputClass = 
Class.forName("org.gnu.freeway.services." + 
inputClasses[i].getName().substring(0, inputClasses[i].getName().length() - 6));
@@ -134,6 +142,7 @@
                                continue;
                        }
                        
+                       //create empty output files
                        File outputSource = new File(sourcesDir, 
stripPackage(inputClass.getName()) + ".java");
                        try {
                                if(!outputSource.createNewFile()) {
@@ -164,6 +173,7 @@
                                continue;
                        }
                        
+                       //get a writer
                        BufferedWriter outputSourceWriter = null;
                        try {
                                outputSourceWriter = new BufferedWriter(new 
FileWriter(outputSource));
@@ -177,8 +187,9 @@
                                continue;
                        }
                        
+                       //write code
                        try {
-                               implementClass(inputClass, outputSourceWriter);
+                               implementClass(inputClass, outputSourceWriter, 
functionTypeSet);
                        } catch(IOException e) {
                                e.printStackTrace();
                                try {
@@ -203,10 +214,262 @@
                        }
                }
                
-               //TODO: generate code for the native portion
+               //begin working on the C side
+               //create native folder
+               if(!nativeCDir.exists())
+                       if(!nativeCDir.mkdirs()) {
+                               try {
+                                       System.err.println("Could not create 
nonexistant native folder \"" + nativeCDir.getCanonicalPath() + "\".");
+                               } catch(IOException ee) {
+                                       System.err.println("Could not create 
nonexistant native folder \"" + nativeCDir.getAbsolutePath() + "\".");
+                               }
+                       }
+               
+               //create empty switch-table.c
+               File switchTableCFile = new File(nativeCDir, "switch-table.c");
+               try {
+                       if(!switchTableCFile.createNewFile()) {
+                               if(!switchTableCFile.delete()) {
+                                       try {
+                                               System.err.println("Could not 
delete existing native file \"" + switchTableCFile.getCanonicalPath() + "\".");
+                                       } catch(IOException ee) {
+                                               System.err.println("Could not 
delete existing native file \"" + switchTableCFile.getAbsolutePath() + "\".");
+                                       }
+                                       return;
+                               }
+                               if(!switchTableCFile.createNewFile()) {
+                                       try {
+                                               System.err.println("Could not 
create native file \"" + switchTableCFile.getCanonicalPath() + "\".");
+                                       } catch(IOException ee) {
+                                               System.err.println("Could not 
create native file \"" + switchTableCFile.getAbsolutePath() + "\".");
+                                       }
+                                       return;
+                               }
+                       }
+               } catch(Exception e) {
+                       e.printStackTrace();
+                       try {
+                               System.err.println("Could not create native 
file \"" + switchTableCFile.getCanonicalPath() + "\".");
+                       } catch(IOException ee) {
+                               System.err.println("Could not create native 
file \"" + switchTableCFile.getAbsolutePath() + "\".");
+                       }
+                       return;
+               }
+               //create empty switch-table.h
+               File switchTableHFile = new File(nativeCDir, "switch-table.h");
+               try {
+                       if(!switchTableHFile.createNewFile()) {
+                               if(!switchTableHFile.delete()) {
+                                       try {
+                                               System.err.println("Could not 
delete existing native file \"" + switchTableHFile.getCanonicalPath() + "\".");
+                                       } catch(IOException ee) {
+                                               System.err.println("Could not 
delete existing native file \"" + switchTableHFile.getAbsolutePath() + "\".");
+                                       }
+                                       return;
+                               }
+                               if(!switchTableHFile.createNewFile()) {
+                                       try {
+                                               System.err.println("Could not 
create native file \"" + switchTableHFile.getCanonicalPath() + "\".");
+                                       } catch(IOException ee) {
+                                               System.err.println("Could not 
create native file \"" + switchTableHFile.getAbsolutePath() + "\".");
+                                       }
+                                       return;
+                               }
+                       }
+               } catch(Exception e) {
+                       e.printStackTrace();
+                       try {
+                               System.err.println("Could not create native 
file \"" + switchTableHFile.getCanonicalPath() + "\".");
+                       } catch(IOException ee) {
+                               System.err.println("Could not create native 
file \"" + switchTableHFile.getAbsolutePath() + "\".");
+                       }
+                       return;
+               }
+               
+               //get writers
+               BufferedWriter switchTableCWriter = null;
+               try {
+                       switchTableCWriter = new BufferedWriter(new 
FileWriter(switchTableCFile));
+               } catch(IOException e) {
+                       e.printStackTrace();
+                       try {
+                               System.err.println("Could not open native file 
\"" + switchTableCFile.getCanonicalPath() + "\".");
+                       } catch(IOException ee) {
+                               System.err.println("Could not open native file 
\"" + switchTableCFile.getAbsolutePath() + "\".");
+                       }
+                       return;
+               }
+               BufferedWriter switchTableHWriter = null;
+               try {
+                       switchTableHWriter = new BufferedWriter(new 
FileWriter(switchTableHFile));
+               } catch(IOException e) {
+                       e.printStackTrace();
+                       try {
+                               System.err.println("Could not open native file 
\"" + switchTableHFile.getCanonicalPath() + "\".");
+                       } catch(IOException ee) {
+                               System.err.println("Could not open native file 
\"" + switchTableHFile.getAbsolutePath() + "\".");
+                       }
+                       return;
+               }
+               
+               //write code
+               try {
+                       writeSwitchTable(switchTableCWriter, 
switchTableHWriter, functionTypeSet);
+               } catch(IOException e) {
+                       e.printStackTrace();
+                       System.err.println("Could not write switch table.");
+                       return;
+               } finally {
+                       try {
+                               switchTableCWriter.flush();
+                       } catch(IOException e) {
+                               e.printStackTrace();
+                       }
+                       try {
+                               switchTableHWriter.flush();
+                       } catch(IOException e) {
+                               e.printStackTrace();
+                       }
+                       try {
+                               switchTableCWriter.close();
+                       } catch(IOException e) {
+                               e.printStackTrace();
+                       }
+                       try {
+                               switchTableHWriter.close();
+                       } catch(IOException e) {
+                               e.printStackTrace();
+                       }
+               }
        }
        
-       public static void implementClass(Class c, Writer writer) throws 
IOException, IllegalArgumentException {
+       public static void writeSwitchTable(Writer writerC, Writer writerH, 
HashSet functionTypeSet) throws IOException {
+               System.err.println("Writing the switch table");
+               writerC.write("// This file was autogenerated by 
SwitchTableGenerator\n");
+               writerH.write("// This file was autogenerated by 
SwitchTableGenerator\n");
+               writerC.write("jobject * jargs = 
(*env)->GetObjectArrayElements(env, arguments, NULL);\n");
+               writerC.write("if(jargs == NULL)\n");
+               writerC.write("  return NULL;\n");
+               writerC.write("switch (functionType) {\n");
+               for(Iterator i = functionTypeSet.iterator(); i.hasNext(); ) {
+                       Integer functionType = (Integer) i.next();
+                       writeSwitch(functionType.intValue(), writerC);
+                       writeFunctionTypeDefine(functionType.intValue(), 
writerH);
+               }
+               writerC.write("  default:\n");
+               writerC.write("    assert(0);\n");
+               writerC.write("}\n");
+               writerC.write("(*env)->ReleaseObjectArrayElements(env, 
arguments, jargs, 0);\n");
+       }
+       
+       public static void writeSwitch(int functionType, Writer writer)  throws 
IOException {
+               int returnType = functionType % CWrapper.MAX_KIND;
+               StringBuffer preBuffer = new StringBuffer("  case " + 
functionType + ": {\n");
+               StringBuffer callBuffer = new StringBuffer("    ((FunctionType" 
+ functionType + ") ((void**)m->modulePtr)[functionOffset])(");
+               StringBuffer postBuffer = new StringBuffer("  }\n");
+               functionType = (functionType - returnType) / CWrapper.MAX_KIND;
+               //a - the current position(base MAX_KIND)
+               //maxA - the initial value of a(puts the arguments in order)
+               //b - the digit in position a
+               int a = (int) Math.max(Math.floor(Math.log(functionType) / 
Math.log(CWrapper.MAX_KIND)), -1);
+               int maxA = a;
+               if(returnType == CWrapper.PTR_KIND) {
+                       preBuffer.append("    jclass returnClass = (jclass) 
jargs[" + (a + 1) + "];\n");
+               }
+               if(returnType != CWrapper.VOID_KIND) {
+                       callBuffer.insert(4, CWrapper.CTYPES[returnType] + " 
cret = ");
+                       postBuffer.insert(0, 
writeCTypeToJTypeReturn(returnType));
+               }
+               while(a >= 0) {
+                       int b = (int) Math.floor(functionType / 
Math.pow(CWrapper.MAX_KIND, a));
+                       if(b == CWrapper.VOID_KIND)
+                               return; //can't have a void argument
+                       preBuffer.append(writeJTypeToCType(b, maxA - a));
+                       if(maxA - a > 0)
+                               callBuffer.append(", ");
+                       callBuffer.append("carg" + (maxA - a));
+                       if(b == CWrapper.PTR_KIND)
+                               postBuffer.insert(0, writeCTypeToJType(b, maxA 
- a));
+                       functionType -= b * Math.pow(CWrapper.MAX_KIND, a--);
+               }
+               writer.write(preBuffer.toString());
+               writer.write(callBuffer.toString() + ");\n");
+               writer.write(postBuffer.toString());
+       }
+       
+       public static String writeCTypeToJTypeReturn(int returnType) {
+               if(returnType == CWrapper.VOID_KIND)
+                       return "";
+               else if(returnType == CWrapper.INT_KIND)
+                       return "    oret = convIntToCInt(cret, env);\n";
+               else if(returnType == CWrapper.PTR_KIND)
+                       return "    oret = convPtrToNewObject(cret, 
returnClass, env);\n";
+               else if(returnType == CWrapper.FLT_KIND)
+                       return "    oret = convFloatToCFloat(cret, env);\n";
+               else if(returnType == CWrapper.LINT_KIND)
+                       return "    oret = convLongToCLong(cret, env);\n";
+               else if(returnType == CWrapper.DBLE_KIND)
+                       return "    oret = convDoubleToCDouble(cret, env);\n";
+               else
+                       return "    //TODO: return cret " + returnType + "\n";
+       }
+       
+       public static String writeCTypeToJType(int returnType, int argnumber) {
+               if(returnType == CWrapper.VOID_KIND)
+                       return "";
+               else if(returnType == CWrapper.INT_KIND)
+                       return "    jargs[" + argnumber + "] = 
convIntToCInt(carg" + argnumber + ", env);\n";
+               else if(returnType == CWrapper.PTR_KIND)
+                       return "    updateObjectFromPtr(jargs[" + argnumber + 
"], carg" + argnumber + ", env);\n";
+               else if(returnType == CWrapper.FLT_KIND)
+                       return "    jargs[" + argnumber + "] = 
convFloatToCFloat(carg" + argnumber + ", env);\n";
+               else if(returnType == CWrapper.LINT_KIND)
+                       return "    jargs[" + argnumber + "] = 
convLongToCLong(carg" + argnumber + ", env);\n";
+               else if(returnType == CWrapper.DBLE_KIND)
+                       return "    jargs[" + argnumber + "] = 
convDoubleToCDouble(carg" + argnumber + ", env);\n";
+               else
+                       return "    //TODO: carg" + argnumber + " -> jarg" + 
argnumber + " " + returnType + "\n";
+       }
+       
+       public static String writeJTypeToCType(int returnType, int argnumber) {
+               if(returnType == CWrapper.VOID_KIND)
+                       return "";
+               else if(returnType == CWrapper.INT_KIND)
+                       return "    " + CWrapper.CTYPES[returnType] + " carg" + 
argnumber + " = convCIntToInt(jargs[" + argnumber + "], env);\n";
+               else if(returnType == CWrapper.PTR_KIND)
+                       return "    " + CWrapper.CTYPES[returnType] + " carg" + 
argnumber + " = convObjectToPtr(jargs[" + argnumber + "], env);\n";
+               else if(returnType == CWrapper.FLT_KIND)
+                       return "    " + CWrapper.CTYPES[returnType] + " carg" + 
argnumber + " = convCFloatToFloat(jargs[" + argnumber + "], env);\n";
+               else if(returnType == CWrapper.LINT_KIND)
+                       return "    " + CWrapper.CTYPES[returnType] + " carg" + 
argnumber + " = convCLongToLong(jargs[" + argnumber + "], env);\n";
+               else if(returnType == CWrapper.DBLE_KIND)
+                       return "    " + CWrapper.CTYPES[returnType] + " carg" + 
argnumber + " = convCDoubleToDouble(jargs[" + argnumber + "], env);\n";
+               else
+                       return "    //TODO: jargs[" + argnumber + "] -> carg" + 
argnumber + " " + returnType + "\n";
+       }
+       
+       public static void writeFunctionTypeDefine(int functionType, Writer 
writer) throws IOException {
+               int returnType = functionType % CWrapper.MAX_KIND;
+               StringBuffer typedef = new StringBuffer("typedef " + 
CWrapper.CTYPES[returnType] + " (FunctionType" + functionType + "*)(");
+               functionType = (functionType - returnType) / CWrapper.MAX_KIND;
+               //a - the current position(base MAX_KIND)
+               //maxA - the initial value of a(puts the arguments in order)
+               //b - the digit in position a
+               int a = (int) Math.floor(Math.log(functionType) / 
Math.log(CWrapper.MAX_KIND));
+               int maxA = a;
+               while(a >= 0) {
+                       int b = (int) Math.floor(functionType / 
Math.pow(CWrapper.MAX_KIND, a));
+                       if(b == CWrapper.VOID_KIND)
+                               return; //can't have a void argument
+                       if(maxA - a > 0)
+                               typedef.append(", ");
+                       typedef.append(CWrapper.CTYPES[b] + " arg" + (maxA - 
a));
+                       functionType -= b * Math.pow(CWrapper.MAX_KIND, a--);
+               }
+               writer.write(typedef.toString() + ");\n");
+       }
+       
+       public static void implementClass(Class c, Writer writer, HashSet 
functionTypeSet) throws IOException, IllegalArgumentException {
                if(!c.isInterface()) {
                        throw new IllegalArgumentException();
                }
@@ -237,10 +500,17 @@
                                arrayBuffer.append(paramName);
                        }
                        buffer.append(") {\n            ");
-                       if(!"void".equals(methods[i].getReturnType().getName()))
+                       
if(!"void".equals(methods[i].getReturnType().getName())) {
                                buffer.append("return (" + 
cleanClassName(methods[i].getReturnType().getName(), imports) + ") ");
+                               if(getArgumentType(methods[i].getReturnType()) 
== CWrapper.PTR_KIND) {
+                                       if(j > 0)
+                                               arrayBuffer.append(", ");
+                                       
arrayBuffer.append(cleanClassName(methods[i].getReturnType().getName(), 
imports) + ".class");
+                               }
+                       }
                        buffer.append("loader.callC(handle, \"" + 
methods[i].getName() + "\", this, new Object[] {" + arrayBuffer + "});\n");
                        buffer.append(" }");
+                       functionTypeSet.add(new 
Integer(getFunctionType(methods[i])));
                        methodList.add(buffer.toString());
                }
                
@@ -282,7 +552,7 @@
                        return input;
                String nameStart = input.substring(0, lastDot - 1);
                String nameEnd = input.substring(lastDot + 1);
-               if("java.lang".equals(nameStart)) 
+               if("java.lang".equals(nameStart))
                        return nameEnd; // already included
                if(importMap == null || importMap.containsKey(nameEnd)) {
                        if(importMap == null || input.equals((String) 
importMap.get(nameEnd)))
@@ -308,7 +578,7 @@
                int ret = 0;
                for (int i=0;i<args.length;i++)
                        ret = ret * CWrapper.MAX_KIND + 
getArgumentType(args[i]);
-               return ret * (CWrapper.MAX_KIND + 1) + 
getArgumentType(m.getReturnType());
+               return ret * CWrapper.MAX_KIND + 
getArgumentType(m.getReturnType());
        }
        
        public static int getArgumentType(Class c) {





reply via email to

[Prev in Thread] Current Thread [Next in Thread]