* Removed all Id tags.
[cacao.git] / src / native / tools / gennativetable.c
index 9157ce58b1e7109b274dd32f5b2aa4f8ecb1e8b4..7a9fe1206be7948473a731787689b67f534ad1e8 100644 (file)
@@ -1,9 +1,9 @@
-/* gennativetable.c - generate nativetable.h for native.c
+/* src/native/tools/gennativetable.c - generate nativetable.h for native.c
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
-   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
-   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
-   Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+   J. Wenninger, Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Christian Thalinger
 
    Changes:
 
-   $Id: gennativetable.c 1832 2004-12-29 13:48:07Z twisti $
-
 */
 
 
+#include "config.h"
+
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "config.h"
-#include "types.h"
+#include "vm/types.h"
+
 #include "cacaoh/headers.h"
-#include "mm/boehm.h"
+#include "mm/gc-common.h"
 #include "mm/memory.h"
 
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-#  include "threads/native/threads.h"
-# else
-#  include "threads/green/threads.h"
-# endif
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
 #endif
 
 #include "toolbox/chain.h"
+#include "vm/classcache.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/loader.h"
-#include "vm/tables.h"
+#include "vm/options.h"
+#include "vm/stringlocal.h"
+#include "vm/suck.h"
+
+
+/* define heap sizes **********************************************************/
+
+#define HEAP_MAXSIZE      4 * 1024 * 1024   /* default 4MB                    */
+#define HEAP_STARTSIZE    100 * 1024        /* default 100kB                  */
+
+#define ACC_NATIVELY_OVERLOADED    0x10000000
+
+
+/* define cacaoh options ******************************************************/
+
+enum {
+       OPT_HELP,
+       OPT_VERSION,
+       OPT_VERBOSE,
+       OPT_BOOTCLASSPATH,
+
+       DUMMY
+};
+
+
+opt_struct opts[] = {
+       { "help",             false, OPT_HELP          },
+       { "version",          false, OPT_VERSION       },
+       { "verbose",          false, OPT_VERBOSE       },
+       { "bootclasspath",    true,  OPT_BOOTCLASSPATH },
+       { NULL,               false, 0                 }
+};
+
+
+static JavaVMInitArgs *gennativetable_options_prepare(int argc, char **argv);
 
 
 int main(int argc, char **argv)
 {
-       s4 i, j, k;
-       char classpath[500] = "";
-       char *cp;
+       JavaVMInitArgs *vm_args;
+       char *bootclasspath;
+
+       chain *nativemethod_chain;
+       classcache_name_entry *nmen;
+       classcache_class_entry *clsen;
        classinfo *c;
+       s4 i;
+       s4 j;
+       u4 slot;
        methodinfo *m;
        methodinfo *m2;
        bool nativelyoverloaded;
-       u4 heapmaxsize = 2 * 1024 * 1024;
-       u4 heapstartsize = 100 * 1024;
-       void *dummy;
 
-       /* XXX change me */
-       char classname[1024];
+#if defined(DISABLE_GC)
+       gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
+#endif
+
+       vm_args = gennativetable_options_prepare(argc, argv);
 
-       if (argc < 2) {
-               printf("Usage: gennativetable class [class...]\n");
-               exit(1);
-       }
+       while ((i = options_get(opts, vm_args)) != OPT_DONE) {
+               switch (i) {
+               case OPT_IGNORE:
+                       break;
+
+               case OPT_HELP:
+/*                     usage(); */
+                       break;
+
+               case OPT_BOOTCLASSPATH:
+                       bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
+                       strcpy(bootclasspath, opt_arg);
+                       break;
+
+               case OPT_VERSION:
+/*                     version(); */
+                       break;
 
-       cp = getenv("CLASSPATH");
-       if (cp) {
-               strcpy(classpath + strlen(classpath), cp);
+               case OPT_VERBOSE:
+                       opt_verbose = true;
+                       loadverbose = true;
+                       linkverbose = true;
+                       break;
+
+               default:
+/*                     usage(); */
+                       ;
+               }
        }
 
        /* initialize the garbage collector */
-       gc_init(heapmaxsize, heapstartsize);
 
-       tables_init();
+       gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
 
-       suck_init(classpath);
-   
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-       initThreadsEarly();
-#endif
-       initLocks();
+#if defined(ENABLE_THREADS)
+       threads_preinit();
 #endif
 
-       loader_init((u1 *) &dummy);
+       /* initialize the string hashtable stuff: lock (must be done
+          _after_ threads_preinit) */
+
+       if (!string_init())
+               throw_main_exception_exit();
+
+       /* initialize the utf8 hashtable stuff: lock, often used utf8 strings
+          (must be done _after_ threads_preinit) */
+
+       if (!utf8_init())
+               throw_main_exception_exit();
+
+       /* initialize the classcache hashtable stuff: lock, hashtable
+          (must be done _after_ threads_preinit) */
+
+       if (!classcache_init())
+               throw_main_exception_exit();
+
+       /* initialize the loader with bootclasspath (must be done _after_
+          thread_preinit) */
+
+       if (!suck_init())
+               throw_main_exception_exit();
+
+       suck_add(bootclasspath);
+
+       /* initialize the loader subsystems (must be done _after_
+       classcache_init) */
+
+       if (!loader_init())
+               throw_main_exception_exit();
 
 
        /*********************** Load JAVA classes  **************************/
 
-       nativeclass_chain = chain_new();
        nativemethod_chain = chain_new();
+       ident_chain = chain_new();
 
-       for (i = 1; i < argc; i++) {
-               cp = argv[i];
+       /* load all classes from bootclasspath */
 
-               /* convert classname */
-               for (j = strlen(cp) - 1; j >= 0; j--) {
-                       switch (cp[j]) {
-                       case '.': cp[j] = '/';
-                               break;
-                       case '_': cp[j] = '$';
-                       }
-               }
-       
-               c = class_new(utf_new_char(cp));
+       loader_load_all_classes();
 
-               /* exceptions are catched with new_exception call */
-               class_load(c);
-               class_link(c);
+       /* link all classes */
 
-               chain_addlast(nativeclass_chain, c);
+       for (slot = 0; slot < hashtable_classcache.size; slot++) {
+               nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
 
-               /* find overloaded methods */
-               for (j = 0; j < c->methodscount; j++) {
-                       m = &(c->methods[j]);
+               for (; nmen; nmen = nmen->hashlink) {
+                       /* iterate over all class entries */
 
-                       if (!(m->flags & ACC_NATIVE))
-                               continue;
+                       for (clsen = nmen->classes; clsen; clsen = clsen->next) {
+                               c = clsen->classobj;
 
-                       if (!m->nativelyoverloaded) {
-                               nativelyoverloaded = false;
-                               
-                               for (k = j + 1; k < c->methodscount; k++) {
-                                       m2 = &(c->methods[k]);
+                               if (c == NULL)
+                                       continue;
+
+                               /* find overloaded methods */
 
-                                       if (!(m2->flags & ACC_NATIVE))
+                               for (i = 0; i < c->methodscount; i++) {
+                                       m = &(c->methods[i]);
+
+                                       if (!(m->flags & ACC_NATIVE))
                                                continue;
 
-                                       if (m->name == m2->name) {
-                                               m2->nativelyoverloaded = true;
-                                               nativelyoverloaded = true;
+                                       if (!(m->flags & ACC_NATIVELY_OVERLOADED)) {
+                                               nativelyoverloaded = false;
+                               
+                                               for (j = i + 1; j < c->methodscount; j++) {
+                                                       m2 = &(c->methods[j]);
+
+                                                       if (!(m2->flags & ACC_NATIVE))
+                                                               continue;
+
+                                                       if (m->name == m2->name) {
+                                                               m2->flags          |= ACC_NATIVELY_OVERLOADED;
+                                                               nativelyoverloaded  = true;
+                                                       }
+                                               }
+
+                                               if (nativelyoverloaded == true)
+                                                       m->flags |= ACC_NATIVELY_OVERLOADED;
                                        }
                                }
-                               m->nativelyoverloaded = nativelyoverloaded;
-                       }
-               }
 
-               for (j = 0; j < c->methodscount; j++) {
-                       m = &(c->methods[j]);
+                               for (j = 0; j < c->methodscount; j++) {
+                                       m = &(c->methods[j]);
 
-                       if (m->flags & ACC_NATIVE) {
-                               chain_addlast(nativemethod_chain, m);
+                                       if (m->flags & ACC_NATIVE) {
+                                               chain_addlast(nativemethod_chain, m);
+                                       }
+                               }
                        }
                }
        }
@@ -164,81 +249,84 @@ int main(int argc, char **argv)
 
        file = stdout;
 
-       fprintf(file, "/* Table of native methods: nativetables.inc */\n");
        fprintf(file, "/* This file is machine generated, don't edit it! */\n\n"); 
 
-       fprintf(file, "#include \"config.h\"\n");
+       m = chain_first(nativemethod_chain);
 
-       c = chain_first(nativeclass_chain);
-       while (c) {
-               gen_header_filename(classname, c->name);
-               fprintf(file, "#include \"native/include/%s.h\"\n", classname);
-               c = chain_next(nativeclass_chain);
+       while (m) {
+               printmethod(m);
+               m = chain_next(nativemethod_chain);
        }
-       chain_free(nativeclass_chain);
 
-       fprintf(file, "\n\n#include \"native/native.h\"\n\n");
-       fprintf(file, "#if defined(STATIC_CLASSPATH)\n\n");
        fprintf(file, "static nativeref nativetable[] = {\n");
 
        m = chain_first(nativemethod_chain);
+
        while (m) {
-               printnativetableentry(m);
+        fprintf(file, "   { \"");
+
+               print_classname(m->class);
+               fprintf(file, "\",\n     \"");
+               utf_fprint_printable_ascii(file, m->name);
+               fprintf(file, "\",\n     \"");
+               utf_fprint_printable_ascii(file, m->descriptor);
+               fprintf(file, "\",\n     ");
+
+               if (m->flags & ACC_STATIC)
+                       fprintf(file, "true");
+               else
+                       fprintf(file, "false");
+
+               fprintf(file, ",\n     ");
+               fprintf(file, "(functionptr) Java_");
+               printID(m->class->name);
+               fprintf(file, "_");
+               printID(m->name);
+        
+               if (m->flags & ACC_NATIVELY_OVERLOADED)
+                       printOverloadPart(m->descriptor);
+
+               fprintf(file,"\n   },\n");
+
                m = chain_next(nativemethod_chain);
        }
+
        chain_free(nativemethod_chain);
 
        fprintf(file, "};\n");
-       fprintf(file, "\n#else\n\n");
-       fprintf(file, "/* Ensure that symbols for functions implemented within cacao are used and    */\n");
-       fprintf(file, "/* exported to dlopen.                                                        */\n\n");
-       fprintf(file, "static functionptr dummynativetable[] = {\n");
 
-       {
-               FILE *implData;
+       fclose(file);
+       
+       /* release all resources */
+
+       loader_close();
 
-               implData = fopen("vm/implementednatives.data", "r");
+       /* everything is ok */
 
-               if (!implData) {
-                       fclose(file);
-                       throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                          "Could not find file");
-               }
+       return 0;
+}
 
-               while (!feof(implData)) {
-                       char functionLine[1024];
-                       functionLine[0] = '\0';
-                       fgets(functionLine, 1024, implData);
 
-                       if (strlen(functionLine) < 2)
-                               continue;
+/* gennativetable_options_prepare **********************************************
 
-                       if (functionLine[strlen(functionLine) - 1] != '\n') {
-                               fclose(implData);
-                               fclose(file);
-                               exit(4);
-                       }
+   Prepare the JavaVMInitArgs.
 
-                       functionLine[strlen(functionLine) - 1] = ',';
-                       fprintf(file,"\t(functionptr) %s\n", functionLine);
-               }
+*******************************************************************************/
 
-               fprintf(file, "\t(functionptr) 0\n");
-               fclose(implData);
-       }
+static JavaVMInitArgs *gennativetable_options_prepare(int argc, char **argv)
+{
+       JavaVMInitArgs *vm_args;
+       s4              i;
 
-       fprintf(file, "};\n");
-       fprintf(file, "\n#endif\n");
-       fclose(file);
-       
-       /* release all resources */
+       vm_args = NEW(JavaVMInitArgs);
 
-       loader_close();
-       tables_close();
+       vm_args->nOptions = argc - 1;
+       vm_args->options  = MNEW(JavaVMOption, argc);
 
-       /* everything is ok */
+       for (i = 1; i < argc; i++)
+               vm_args->options[i - 1].optionString = argv[i];
 
-       return 0;
+       return vm_args;
 }