-/* 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);
+ }
+ }
}
}
}
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;
}