-/* cacao/cacao.c - contains main() of cacao
+/* src/cacao/cacao.c - contains main() of cacao
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,
- TU Wien
+ Institut f. Computersprachen - TU Wien
This file is part of CACAO.
Changes: Andi Krall
Mark Probst
Philipp Tomsich
+ Christian Thalinger
This module does the following tasks:
- Command line option handling
- Calling the class loader
- Running the main method
- $Id: cacao.c 1686 2004-12-05 23:56:47Z twisti $
+ $Id: cacao.c 2022 2005-03-09 12:07:57Z twisti $
*/
#include <stdlib.h>
#include <string.h>
+#include "config.h"
#include "cacao/cacao.h"
#include "mm/boehm.h"
#include "mm/memory.h"
+#include "native/jni.h"
#include "native/native.h"
#include "toolbox/logging.h"
#include "vm/exceptions.h"
#include "vm/loader.h"
#include "vm/options.h"
#include "vm/statistics.h"
+#include "vm/stringlocal.h"
#include "vm/tables.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.h"
#ifdef TYPEINFO_DEBUG_TEST
-#include "typeinfo.h"
+#include "vm/jit/verify/typeinfo.h"
#endif
+/* define heap sizes **********************************************************/
+
+#define HEAP_MAXSIZE 64 * 1024 * 1024; /* default 64MB */
+#define HEAP_STARTSIZE 2 * 1024 * 1024; /* default 2MB */
+
+
+/* Invocation API variables ***************************************************/
+
+JavaVM *jvm; /* denotes a Java VM */
+JNIEnv *env; /* pointer to native method interface */
+
+JDK1_1InitArgs vm_args; /* JDK 1.1 VM initialization arguments */
+
+
bool cacao_initializing;
-char *classpath; /* contains classpath */
+char *bootclasspath; /* contains the boot classpath */
+char *classpath; /* contains the classpath */
+
char *mainstring;
static classinfo *mainclass;
void **stackbottom = 0;
#endif
+
/* define command line options ************************************************/
-#define OPT_CLASSPATH 2
-#define OPT_D 3
-#define OPT_MS 4
-#define OPT_MX 5
-#define OPT_VERBOSE1 6
-#define OPT_VERBOSE 7
-#define OPT_VERBOSEGC 8
-#define OPT_VERBOSECALL 9
-#define OPT_NOIEEE 10
-#define OPT_SOFTNULL 11
-#define OPT_TIME 12
-#define OPT_STAT 13
-#define OPT_LOG 14
-#define OPT_CHECK 15
-#define OPT_LOAD 16
-#define OPT_METHOD 17
-#define OPT_SIGNATURE 18
-#define OPT_SHOW 19
-#define OPT_ALL 20
-#define OPT_OLOOP 24
-#define OPT_INLINING 25
-#ifdef STATIC_ANALYSIS
-#define OPT_RT 26
-#define OPT_XTA 27
-#define OPT_VTA 28
-#endif
-#define OPT_VERBOSETC 29
-#define OPT_NOVERIFY 30
-#define OPT_LIBERALUTF 31
+#define OPT_CLASSPATH 2
+#define OPT_D 3
+#define OPT_MS 4
+#define OPT_MX 5
+#define OPT_VERBOSE1 6
+#define OPT_VERBOSE 7
+#define OPT_VERBOSEGC 8
+#define OPT_VERBOSECALL 9
+#define OPT_NOIEEE 10
+#define OPT_SOFTNULL 11
+#define OPT_TIME 12
+#define OPT_STAT 13
+#define OPT_LOG 14
+#define OPT_CHECK 15
+#define OPT_LOAD 16
+#define OPT_METHOD 17
+#define OPT_SIGNATURE 18
+#define OPT_SHOW 19
+#define OPT_ALL 20
+#define OPT_OLOOP 24
+#define OPT_INLINING 25
+
+#define STATIC_ANALYSIS
+#if defined(STATIC_ANALYSIS)
+# define OPT_RT 26
+# define OPT_XTA 27
+# define OPT_VTA 28
+#endif /* STATIC_ANALYSIS */
+
+#define OPT_VERBOSETC 29
+#define OPT_NOVERIFY 30
+#define OPT_LIBERALUTF 31
#define OPT_VERBOSEEXCEPTION 32
#define OPT_EAGER 33
-#ifdef LSRA
-#define OPT_LSRA 34
-#endif
+
+#if defined(LSRA)
+# define OPT_LSRA 34
+#endif /* LSRA */
+
+#define OPT_JAR 35
+#define OPT_BOOTCLASSPATH 36
+#define OPT_BOOTCLASSPATH_A 37
+#define OPT_BOOTCLASSPATH_P 38
+#define OPT_VERSION 39
+
opt_struct opts[] = {
- {"classpath", true, OPT_CLASSPATH},
- {"cp", true, OPT_CLASSPATH},
- {"D", true, OPT_D},
- {"Xms", true, OPT_MS},
- {"Xmx", true, OPT_MX},
- {"ms", true, OPT_MS},
- {"mx", true, OPT_MX},
- {"noasyncgc", false, OPT_IGNORE},
- {"noverify", false, OPT_NOVERIFY},
- {"liberalutf", false, OPT_LIBERALUTF},
- {"oss", true, OPT_IGNORE},
- {"ss", true, OPT_IGNORE},
- {"v", false, OPT_VERBOSE1},
- {"verbose", false, OPT_VERBOSE},
- {"verbosegc", false, OPT_VERBOSEGC},
- {"verbosecall", false, OPT_VERBOSECALL},
- {"verboseexception", false, OPT_VERBOSEEXCEPTION},
+ { "classpath", true, OPT_CLASSPATH },
+ { "cp", true, OPT_CLASSPATH },
+ { "D", true, OPT_D },
+ { "Xms", true, OPT_MS },
+ { "Xmx", true, OPT_MX },
+ { "ms", true, OPT_MS },
+ { "mx", true, OPT_MX },
+ { "noasyncgc", false, OPT_IGNORE },
+ { "noverify", false, OPT_NOVERIFY },
+ { "liberalutf", false, OPT_LIBERALUTF },
+ { "oss", true, OPT_IGNORE },
+ { "ss", true, OPT_IGNORE },
+ { "v", false, OPT_VERBOSE1 },
+ { "verbose", false, OPT_VERBOSE },
+ { "verbosegc", false, OPT_VERBOSEGC },
+ { "verbosecall", false, OPT_VERBOSECALL },
+ { "verboseexception", false, OPT_VERBOSEEXCEPTION },
#ifdef TYPECHECK_VERBOSE
- {"verbosetc", false, OPT_VERBOSETC},
+ { "verbosetc", false, OPT_VERBOSETC },
#endif
#if defined(__ALPHA__)
- {"noieee", false, OPT_NOIEEE},
+ { "noieee", false, OPT_NOIEEE },
#endif
- {"softnull", false, OPT_SOFTNULL},
- {"time", false, OPT_TIME},
- {"stat", false, OPT_STAT},
- {"log", true, OPT_LOG},
- {"c", true, OPT_CHECK},
- {"l", false, OPT_LOAD},
- { "eager", false, OPT_EAGER },
- {"m", true, OPT_METHOD},
- {"sig", true, OPT_SIGNATURE},
- {"s", true, OPT_SHOW},
- {"all", false, OPT_ALL},
- {"oloop", false, OPT_OLOOP},
- {"i", true, OPT_INLINING},
+ { "softnull", false, OPT_SOFTNULL },
+ { "time", false, OPT_TIME },
+#if defined(STATISTICS)
+ { "stat", false, OPT_STAT },
+#endif
+ { "log", true, OPT_LOG },
+ { "c", true, OPT_CHECK },
+ { "l", false, OPT_LOAD },
+ { "eager", false, OPT_EAGER },
+ { "m", true, OPT_METHOD },
+ { "sig", true, OPT_SIGNATURE },
+ { "s", true, OPT_SHOW },
+ { "all", false, OPT_ALL },
+ { "oloop", false, OPT_OLOOP },
+ { "i", true, OPT_INLINING },
#ifdef STATIC_ANALYSIS
- {"rt", false, OPT_RT},
- {"xta", false, OPT_XTA},
- {"vta", false, OPT_VTA},
+ { "rt", false, OPT_RT },
+ { "xta", false, OPT_XTA },
+ { "vta", false, OPT_VTA },
#endif
#ifdef LSRA
- {"lsra", false, OPT_LSRA},
+ { "lsra", false, OPT_LSRA },
#endif
- {NULL, false, 0}
+ { "jar", false, OPT_JAR },
+ { "Xbootclasspath:", true, OPT_BOOTCLASSPATH },
+ { "Xbootclasspath/a:", true, OPT_BOOTCLASSPATH_A },
+ { "Xbootclasspath/p:", true, OPT_BOOTCLASSPATH_P },
+ { "version", false, OPT_VERSION },
+ { NULL, false, 0 }
};
static void usage()
{
- printf("USAGE: cacao [options] classname [program arguments]\n");
+ printf("Usage: cacao [options] classname [program arguments]\n\n");
+
printf("Options:\n");
- printf(" -cp path ............. specify a path to look for classes\n");
- printf(" -classpath path ...... specify a path to look for classes\n");
- printf(" -Dpropertyname=value . add an entry to the property list\n");
- printf(" -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
- printf(" -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
- printf(" -mx maxmem[kK|mM] .... specify the size for the heap\n");
- printf(" -ms initmem[kK|mM] ... specify the initial size for the heap\n");
+ printf(" -cp <path> specify a path to look for classes\n");
+ printf(" -classpath <path> specify a path to look for classes\n");
+ printf(" -jar jarfile execute a jar file\n");
+ printf(" -D<name>=<value> add an entry to the property list\n");
+ printf(" -Xmx<size>[kK|mM] specify the size for the heap\n");
+ printf(" -Xms<size>[kK|mM] specify the initial size for the heap\n");
+ printf(" -mx<size>[kK|mM] specify the size for the heap\n");
+ printf(" -ms<size>[kK|mM] specify the initial size for the heap\n");
+ printf(" -Xbootclasspath:<path> set search path for bootstrap classes and resources\n");
+ printf(" -Xbootclasspath/a:<path> append to end of bootstrap class path\n");
+ printf(" -Xbootclasspath/p:<path> prepend in front of bootstrap class path\n");
printf(" -v ................... write state-information\n");
printf(" -verbose ............. write more information\n");
printf(" -verbosegc ........... write message for each GC\n");
#ifdef TYPECHECK_VERBOSE
printf(" -verbosetc ........... write debug messages while typechecking\n");
#endif
+ printf(" -version print product version and exit\n");
#if defined(__ALPHA__)
printf(" -noieee .............. don't use ieee compliant arithmetic\n");
#endif
printf(" -liberalutf........... don't warn about overlong UTF-8 sequences\n");
printf(" -softnull ............ use software nullpointer check\n");
printf(" -time ................ measure the runtime\n");
+#if defined(STATISTICS)
printf(" -stat ................ detailed compiler statistics\n");
+#endif
printf(" -log logfile ......... specify a name for the logfile\n");
printf(" -c(heck)b(ounds) ..... don't check array bounds\n");
printf(" s(ync) ....... don't check for synchronization\n");
}
+/* version *********************************************************************
+
+ Only prints cacao version information and exits.
+
+*******************************************************************************/
+
+static void version()
+{
+ printf("cacao "VERSION"\n");
+ exit(0);
+}
+
+
#ifdef TYPECHECK_STATISTICS
void typecheck_print_statistics(FILE *file);
#endif
+
+/* getmainclassfromjar ************************************************************
+
+ gets the name of the main class form a jar's manifest file
+
+**********************************************************************************/
+
+char *getmainclassnamefromjar(JNIEnv *env, char *mainstring)
+{
+ jclass class;
+ jmethodID mid;
+ jobject obj;
+
+ class = (*env)->FindClass(env, "java/util/jar/JarFile");
+ if (class == NULL) {
+ log_text("unable to find java.util.jar.JarFile");
+ throw_main_exception_exit();
+ }
+
+ mid = (*env)->GetMethodID(NULL, class, "<init>","(Ljava/lang/String;)V");
+ if (mid == NULL) {
+ log_text("unable to find constructor in java.util.jar.JarFile");
+ cacao_exit(1);
+ }
+
+ /* open jarfile */
+ obj = (*env)->NewObject(NULL,class,mid,((*env)->NewStringUTF(NULL,(char*)mainstring)));
+ if ((*env)->ExceptionOccurred(NULL) != NULL) {
+ (*env)->ExceptionDescribe(NULL);
+ cacao_exit(1);
+ }
+
+ mid = (*env)->GetMethodID(NULL, class, "getManifest","()Ljava/util/jar/Manifest;");
+ if (mid == NULL) {
+ log_text("unable to find getMainfest method");
+ cacao_exit(1);
+ }
+
+ /* get manifest object */
+ obj = (*env)->CallObjectMethod(NULL,obj,mid);
+ if ((*env)->ExceptionOccurred(NULL) != NULL) {
+ (*env)->ExceptionDescribe(NULL);
+ cacao_exit(1);
+ }
+
+ mid = (*env)->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getMainAttributes","()Ljava/util/jar/Attributes;");
+ if (mid == NULL) {
+ log_text("unable to find getMainAttributes method");
+ cacao_exit(1);
+ }
+
+ /* get Main Attributes */
+ obj = (*env)->CallObjectMethod(NULL,obj,mid);
+ if ((*env)->ExceptionOccurred(NULL) != NULL) {
+ (*env)->ExceptionDescribe(NULL);
+ cacao_exit(1);
+ }
+
+
+ mid = (*env)->GetMethodID(NULL, (jclass)((java_objectheader*) obj)->vftbl->class, "getValue","(Ljava/lang/String;)Ljava/lang/String;");
+ if (mid == NULL) {
+ log_text("unable to find getValue method");
+ cacao_exit(1);
+ }
+
+ /* get property Main-Class */
+ obj = (*env)->CallObjectMethod(NULL,obj,mid,(*env)->NewStringUTF(NULL,"Main-Class"));
+ if ((*env)->ExceptionOccurred(NULL) != NULL) {
+ (*env)->ExceptionDescribe(NULL);
+ cacao_exit(1);
+ }
+
+ return javastring_tochar((java_objectheader *) obj);
+}
+
+
/*
* void exit_handler(void)
* -----------------------
if (opt_verbose || getcompilingtime || opt_stat) {
log_text("CACAO terminated");
+
+#if defined(STATISTICS)
if (opt_stat) {
print_stats();
#ifdef TYPECHECK_STATISTICS
typecheck_print_statistics(get_logfile());
#endif
}
+
if (getcompilingtime)
print_times();
mem_usagelog(1);
+#endif
}
}
/********** interne (nur fuer main relevante Optionen) **************/
char logfilename[200] = "";
- u4 heapmaxsize = 64 * 1024 * 1024;
- u4 heapstartsize = 200 * 1024;
+ u4 heapmaxsize;
+ u4 heapstartsize;
char *cp;
s4 cplen;
bool startit = true;
char *specificmethodname = NULL;
char *specificsignature = NULL;
+ bool jar = false;
#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
stackbottom = &dummy;
/************ Collect info from the environment ************************/
- /* set an initial, minimal classpath */
- classpath = MNEW(char, 2);
- strcpy(classpath, ".");
+ /* set the bootclasspath */
+
+ cp = getenv("BOOTCLASSPATH");
+ if (cp) {
+ bootclasspath = MNEW(char, strlen(cp) + 1);
+ strcpy(bootclasspath, cp);
+
+ } else {
+ cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
+
+ bootclasspath = MNEW(char, cplen + 1);
+ strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
+ strcat(bootclasspath, CACAO_RT_JAR_PATH);
+ }
+
+
+ /* set the classpath */
- /* get classpath environment */
cp = getenv("CLASSPATH");
if (cp) {
- classpath = MREALLOC(classpath,
- char,
- strlen(classpath),
- strlen(classpath) + 1 + strlen(cp) + 1);
- strcat(classpath, ":");
+ classpath = MNEW(char, strlen(cp) + 1);
strcat(classpath, cp);
+
+ } else {
+ classpath = MNEW(char, 2);
+ strcpy(classpath, ".");
}
+
/***************** Interpret the command line *****************/
checknull = false;
opt_noieee = false;
+ heapmaxsize = HEAP_MAXSIZE;
+ heapstartsize = HEAP_STARTSIZE;
+
+
while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
switch (i) {
case OPT_IGNORE:
break;
+ case OPT_BOOTCLASSPATH:
+ /* Forget default bootclasspath and set the argument as new boot */
+ /* classpath. */
+ MFREE(bootclasspath, char, strlen(bootclasspath));
+
+ bootclasspath = MNEW(char, strlen(opt_arg) + 1);
+ strcpy(bootclasspath, opt_arg);
+ break;
+
+ case OPT_BOOTCLASSPATH_A:
+ /* append to end of bootclasspath */
+ cplen = strlen(bootclasspath);
+
+ bootclasspath = MREALLOC(bootclasspath,
+ char,
+ cplen,
+ cplen + 1 + strlen(opt_arg) + 1);
+
+ strcat(bootclasspath, ":");
+ strcat(bootclasspath, opt_arg);
+ break;
+
+ case OPT_BOOTCLASSPATH_P:
+ /* prepend in front of bootclasspath */
+ cp = bootclasspath;
+ cplen = strlen(cp);
+
+ bootclasspath = MNEW(char, strlen(opt_arg) + 1 + cplen + 1);
+
+ strcpy(bootclasspath, opt_arg);
+ strcat(bootclasspath, ":");
+ strcat(bootclasspath, cp);
+
+ MFREE(cp, char, cplen);
+ break;
+
case OPT_CLASSPATH:
/* forget old classpath and set the argument as new classpath */
MFREE(classpath, char, strlen(classpath));
classpath = MNEW(char, strlen(opt_arg) + 1);
strcpy(classpath, opt_arg);
break;
-
+
+ case OPT_JAR:
+ jar = true;
+ break;
+
case OPT_D:
{
- int n;
- int l = strlen(opt_arg);
- for (n = 0; n < l; n++) {
- if (opt_arg[n] == '=') {
- opt_arg[n] = '\0';
- create_property(opt_arg, opt_arg + n + 1);
+ for (j = 0; j < strlen(opt_arg); j++) {
+ if (opt_arg[j] == '=') {
+ opt_arg[j] = '\0';
+ create_property(opt_arg, opt_arg + j + 1);
goto didit;
}
}
- usage();
+
+ /* if no '=' is given, just create an empty property */
+ create_property(opt_arg, "");
didit: ;
}
case OPT_VERBOSECALL:
runverbose = true;
break;
-
+
+ case OPT_VERSION:
+ version();
+ break;
+
case OPT_NOIEEE:
opt_noieee = true;
break;
getloadingtime = true;
break;
+#if defined(STATISTICS)
case OPT_STAT:
opt_stat = true;
break;
+#endif
case OPT_LOG:
strcpy(logfilename, opt_arg);
switch (opt_arg[j]) {
case 'n':
/* define in options.h; Used in main.c, jit.c & inline.c */
- #ifdef INAFTERMAIN
+#ifdef INAFTERMAIN
useinliningm = true;
useinlining = false;
- #else
+#else
useinlining = true;
- #endif
+#endif
break;
case 'v':
inlinevirtuals = true;
#ifdef STATIC_ANALYSIS
case OPT_RT:
- opt_rt = true;
+ opt_rt = true; /* default for inlining */
break;
case OPT_XTA:
- opt_xta = false; /**not yet **/
+ opt_xta = true; /* in test currently */
break;
case OPT_VTA:
+ printf("\nVTA is not yet available\n");
+ opt_vta = false;
/***opt_vta = true; not yet **/
break;
#endif
#ifdef LSRA
case OPT_LSRA:
-#if defined(__I386__) || defined(__ALPHA__)
+#if defined(__I386__) || defined(__ALPHA__) || defined (__X86_64__) || defined(__POWERPC__)
opt_lsra = true;
#else
printf("LSRA not available for this architecture\n");
#endif
default:
+ printf("Unknown option: %s\n", argv[opt_ind]);
usage();
}
}
usage();
- /* insert the rt.jar in front of all other classpath entries */
-
- cplen = strlen(INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH);
- cp = classpath;
-
- classpath = MNEW(char, cplen + strlen(classpath) + 1);
- strcpy(classpath, INSTALL_PREFIX);
- strcat(classpath, CACAO_RT_JAR_PATH);
- strcat(classpath, cp);
-
- MFREE(cp, char, strlen(cp));
-
-
/* transform dots into slashes in the class name */
mainstring = argv[opt_ind++];
- for (i = strlen(mainstring) - 1; i >= 0; i--) {
- if (mainstring[i] == '.') mainstring[i] = '/';
- }
+ if (!jar) {
+ /* do not mangle jar filename */
+ for (i = strlen(mainstring) - 1; i >= 0; i--) {
+ if (mainstring[i] == '.') mainstring[i] = '/';
+ }
+ } else {
+ /* put jarfile in classpath */
+ cp = classpath;
+ classpath = MNEW(char, strlen(mainstring) + 1 + strlen(classpath) + 1);
+ strcpy(classpath, mainstring);
+ strcat(classpath, ":");
+ strcat(classpath, cp);
+
+ MFREE(cp, char, strlen(cp));
+ }
/**************************** Program start *****************************/
log_init(logfilename);
+
if (opt_verbose)
log_text("CACAO started -------------------------------------------------------");
+ /* initialize JavaVM */
+
+ vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
+
+ /* Get the default initialization arguments and set the class path */
+
+ JNI_GetDefaultJavaVMInitArgs(&vm_args);
+ vm_args.classpath = classpath;
+
+ /* load and initialize a Java VM, return a JNI interface pointer in env */
+
+ JNI_CreateJavaVM(&jvm, &env, &vm_args);
+
+
/* initialize the garbage collector */
+
gc_init(heapmaxsize, heapstartsize);
tables_init();
+
+ /* initialize the loader with bootclasspath and append classpath entries */
+
+ suck_init(bootclasspath);
suck_init(classpath);
cacao_initializing = true;
/* initializes jit compiler and codegen stuff */
jit_init();
+ /* initialize some cacao subsystems */
+
+ utf8_init();
+ class_init_foo();
loader_init((u1 *) &dummy);
- /* initialize exceptions used in the system */
- if (!init_system_exceptions())
+ if (!native_init())
throw_main_exception_exit();
- native_loadclasses();
+ if (!exceptions_init())
+ throw_main_exception_exit();
#if defined(USE_THREADS)
initThreads((u1 *) &dummy);
classpath 0.09. Another important thing is, that this has to happen
after initThreads!!! */
- if (!class_init(class_new(utf_new_char("java/lang/System"))))
+ if (!class_init(class_java_lang_System))
throw_main_exception_exit();
-
-
-/* jni_init(); */
cacao_initializing = false;
- /************************* Start worker routines ********************/
+
+ /* start worker routines **************************************************/
if (startit) {
- methodinfo *mainmethod;
+ classinfo *cl; /* java/lang/ClassLoader */
+ classinfo *mainclass; /* java/lang/Class */
+ methodinfo *m;
java_objectarray *a;
- s4 status;
+ s4 status;
/* set return value to OK */
+
status = 0;
- /* create, load and link the main class */
- mainclass = class_new(utf_new_char(mainstring));
+ if (jar) {
+ /* open jar file with java.util.jar.JarFile */
+ mainstring = getmainclassnamefromjar((JNIEnv *) &env, mainstring);
+ }
- if (!class_load(mainclass))
- throw_main_exception_exit();
+ /* get system classloader */
- if (!class_link(mainclass))
+ m = class_resolveclassmethod(class_java_lang_ClassLoader,
+ utf_new_char("getSystemClassLoader"),
+ utf_new_char("()Ljava/lang/ClassLoader;"),
+ class_java_lang_Object,
+ false);
+
+ cl = (classinfo *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
+
+ /* get `loadClass' method */
+
+ m = class_resolveclassmethod(cl->header.vftbl->class,
+ utf_new_char("loadClass"),
+ utf_new_char("(Ljava/lang/String;)Ljava/lang/Class;"),
+ class_java_lang_Object,
+ false);
+
+ /* load the main class */
+
+ mainclass =
+ (classinfo *) asm_calljavafunction(m,
+ cl,
+ javastring_new_char(mainstring),
+ NULL,
+ NULL);
+
+ /* error loading class, clear exceptionptr for new exception */
+
+ if (*exceptionptr || !mainclass) {
+/* *exceptionptr = NULL; */
+
+/* *exceptionptr = */
+/* new_exception_message(string_java_lang_NoClassDefFoundError, */
+/* mainstring); */
throw_main_exception_exit();
+ }
- mainmethod = class_resolveclassmethod(mainclass,
- utf_new_char("main"),
- utf_new_char("([Ljava/lang/String;)V"),
- mainclass,
- false);
+ /* find the `main' method of the main class */
- /* problems with main method? */
-/* if (*exceptionptr) */
-/* throw_exception_exit(); */
+ m = class_resolveclassmethod(mainclass,
+ utf_new_char("main"),
+ utf_new_char("([Ljava/lang/String;)V"),
+ class_java_lang_Object,
+ false);
/* there is no main method or it isn't static */
- if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
+
+ if (*exceptionptr || !m || !(m->flags & ACC_STATIC)) {
+ *exceptionptr = NULL;
+
*exceptionptr =
new_exception_message(string_java_lang_NoSuchMethodError,
"main");
throw_main_exception_exit();
}
+ /* build argument array */
+
a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
for (i = opt_ind; i < argc; i++) {
a->data[i - opt_ind] =
#endif
/*class_showmethods(currentThread->group->header.vftbl->class); */
- *threadrootmethod = mainmethod;
-
+ *threadrootmethod = m;
/* here we go... */
- asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
+
+ asm_calljavafunction(m, a, NULL, NULL, NULL);
/* exception occurred? */
if (*exceptionptr) {
/* now exit the JavaVM */
+/* (*jvm)->DestroyJavaVM(jvm); */
+
cacao_exit(status);
}
/* call the exit function with passed exit status */
- asm_calljavafunction(m,
-#if POINTERSIZE == 8
- (void *) (s8) status,
-#else
- (void *) status,
-#endif
- NULL,
- NULL,
- NULL);
+ /* both inlinevirtual and outsiders not allowed on exit */
+ /* not sure if permanant or temp restriction */
+ if (inlinevirtuals) inlineoutsiders = false;
+
+ asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
/* this should never happen */