main.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 782 行 · 第 1/2 页
C
782 行
/* * main.c * Kick off program. * * Copyright (c) 1996-2000 * Transvirtual Technologies, Inc. All rights reserved. * * Cross-language profiling changes contributed by * the Flux Research Group, Department of Computer Science, * University of Utah, http://www.cs.utah.edu/flux/ * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "config.h"#include "config-std.h"#include "config-mem.h"#include "debug.h"#include "classMethod.h"#include "kaffe/jtypes.h"#include "native.h"#include "constants.h"#include "support.h"#include "errors.h"#include "thread.h"#include "system.h"#include "md.h"#include "ltdl.h"#include "version.h"#include "debugFile.h"#include "xprofiler.h"#include "fileSections.h"#include "feedback.h"#include "methodCache.h"#include "external.h"#if defined(KAFFE_PROFILER)extern int profFlag;#endif#include "jni.h"JavaVMInitArgs vmargs;JNIEnv* env;JavaVM* vm;static int isJar = 0;static char *jvm_onload;static int options(char**);static void usage(void);static size_t parseSize(char*);static int checkException(void);static int main2(JNIEnv* env, char *argv[], int farg, int argc);#define KAFFEHOME "KAFFEHOME"#define CLASSPATH1 "KAFFECLASSPATH"#define LIBRARYPATH1 "KAFFELIBRARYPATH"#define CLASSPATH2 "CLASSPATH"#define LIBRARYPATH2 "LD_LIBRARY_PATH"#define BOOTCLASSPATH "BOOTCLASSPATH"/* * MAIN */intmain(int argc, char* argv[]){ int farg; char* cp;#if defined(MAIN_MD) /* Machine specific main first */ MAIN_MD;#endif vmargs.version = JAVA_VERSION_HEX;#if defined(KAFFE_PROFILER) profFlag = 0;#endif JNI_GetDefaultJavaVMInitArgs(&vmargs); /* set up libtool/libltdl dlopen emulation */ LTDL_SET_PRELOADED_SYMBOLS();#if defined(KAFFE_VMDEBUG) cp = getenv("KAFFE_VMDEBUG"); if (cp != 0) dbgSetMaskStr(cp);#endif cp = getenv(BOOTCLASSPATH); vmargs.bootClasspath = cp; cp = getenv(CLASSPATH1); if (cp == 0) { cp = getenv(CLASSPATH2);#if defined(DEFAULT_CLASSPATH) if (cp == 0) { cp = DEFAULT_CLASSPATH; }#endif } vmargs.classpath = cp; cp = getenv(LIBRARYPATH1); if (cp == 0) { cp = getenv(LIBRARYPATH2); } vmargs.libraryhome = cp; cp = getenv(KAFFEHOME); if (cp == 0) {#if defined(DEFAULT_KAFFEHOME) cp = DEFAULT_KAFFEHOME;#endif } vmargs.classhome = cp; /* Process program options */ farg = options(argv); argc = argc - farg;#if defined(KAFFE_XPROFILER) if( xProfFlag ) { if( !enableXCallGraph() ) { fprintf(stderr, "Unable to initialize cross " "language profiling\n"); xProfFlag = 0; } }#endif /* Get the class name to start with */ if (argv[farg] == 0) { usage(); exit(1); } /* Initialise */ JNI_CreateJavaVM(&vm, &env, &vmargs); /* Handle the '-Xrun' argument. */ if( jvm_onload != NULL ) { char *libpath, *libargs; char errbuf[512]; int index; /* XXX Pull findLibrary() from the JanosVM. */ libpath = &jvm_onload[2]; libpath[0] = 'l'; libpath[1] = 'i'; libpath[2] = 'b'; if( (libargs = strchr(jvm_onload, ':')) != NULL ) { *libargs = '\0'; libargs += 1; } index = loadNativeLibrary(libpath, errbuf, sizeof(errbuf)); if( index > 0 ) { jint (*onload_func)(JavaVM *jvm, char *, void *); if( (onload_func = loadNativeLibrarySym("JVM_OnLoad")) != NULL ) { (void)onload_func(vm, libargs, NULL); } } else { fprintf(stderr, "Unable to load %s: %s\n", libpath, errbuf); exit(1); } } return (main2(env, argv, farg, argc));}/* * Note: * Why do we split main in two parts? * * During initialisation, which is invoked in JNI_CreateJavaVM, we will * estimate the upper end of the main stack by taking the address of a * local variable. The upper end of the main stack is important since * it tells the conservative garbage collector the upper boundary up to * which it must scan the stack (stackEnd in the thread context). * (Replace stackEnd with stackBase and upper with lower if your stack * grows upward.) * * To ensure that no references will be stored on the stack above that * estimated point, we will allocate 1K on the stack as a safe zone. * * The old approach would have the initialisation code guess how much * it must add to the address of the local variable to find the actual * upper end up to which the gc must look for local variables. * The problem with that approach is what if the code guesses wrong? * If it guesses too low, we will lose objects. If it guesses too * high, however, the gc might segfault when trying to scan the stack. * * With the new approach some guessing is still involved: * we guess how big the safe zone should be. If we guess too small, * we will lose objects. If we guess too big, however, all we do is to * waste memory on the main stack. * Weighing the consequences, the new approach seems better. * Does anybody have a better solution? *//* * MAIN, part II */static intmain2(JNIEnv* env, char *argv[], int farg, int argc){ char gc_safe_zone[1024]; jarray args; jclass lcls; jclass cls; jclass mcls; jmethodID cmth; jmethodID lmth; jmethodID mmth; jobject str; jobject loader; int i; char* exec; /* make sure no compiler optimizes this away */ gc_safe_zone[0] = gc_safe_zone[sizeof gc_safe_zone - 1] = 0; /* Executable is a JAR? Use the JAR launcher */ if (isJar != 0) { exec = "kaffe.jar.ExecJar"; mcls = (*env)->FindClass(env, exec); if (checkException()) goto done; } else { exec = argv[farg]; farg++; argc--; /* Get the application class loader class */ lcls = (*env)->FindClass(env, "kaffe.lang.AppClassLoader"); if (checkException()) goto done; /* ... and then get the singleton. */ cmth = (*env)->GetStaticMethodID(env, lcls, "getSingleton", "()Ljava/lang/ClassLoader;"); if (checkException()) goto done; loader = (*env)->CallStaticObjectMethod(env, lcls, cmth); if (checkException()) goto done; /* Load the main class into the AppClassLoader */ lmth = (*env)->GetMethodID(env, lcls, "loadClass", "(Ljava/lang/String;Z)Ljava/lang/Class;"); if (checkException()) goto done; DBG(VMCLASSLOADER, /* Announce when VM calls class loaders.. */ dprintf("Calling user-defined \"startup\" class loader " "kaffe/lang/AppClassLoader - loadClass(%s)\n", exec); ) mcls = (*env)->CallObjectMethod(env, loader, lmth, (*env)->NewStringUTF(env, exec), false); if (checkException()) goto done; } /* ... and run main. */ mmth = (*env)->GetStaticMethodID(env, mcls, "main", "([Ljava/lang/String;)V"); if (checkException()) goto done; /* Build an array of strings as the arguments */ cls = (*env)->FindClass(env, "java/lang/String"); if (checkException()) goto done; args = (*env)->NewObjectArray(env, argc, cls, 0); if (checkException()) goto done; for (i = 0; i < argc; i++) { str = (*env)->NewStringUTF(env, argv[farg+i]); if (checkException()) goto done; (*env)->SetObjectArrayElement(env, args, i, str); if (checkException()) goto done; } /* Call method, check for errors and then exit */ (*env)->CallStaticVoidMethod(env, mcls, mmth, args); (void)checkException();done: /* We're done. We are the "main thread" and so are required to call (*vm)->DestroyJavaVM() instead of (*vm)->DetachCurrentThread() */ (*vm)->DestroyJavaVM(vm); return (0);}static intcheckException(void){ jobject e; jclass eiic; /* Display exception stack trace */ if ((e = (*env)->ExceptionOccurred(env)) == NULL) return (0); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); /* Display inner exception in ExceptionInInitializerError case */ eiic = (*env)->FindClass(env, "java/lang/ExceptionInInitializerError"); if ((*env)->ExceptionOccurred(env) != NULL) { (*env)->ExceptionClear(env); return (1); } if ((*env)->IsInstanceOf(env, e, eiic)) { e = (*env)->CallObjectMethod(env, e, (*env)->GetMethodID(env, (*env)->GetObjectClass(env, e), "getException", "()Ljava/lang/Throwable;")); if ((*env)->ExceptionOccurred(env) != NULL) { (*env)->ExceptionClear(env); return (1); } if (e != NULL) { (*env)->Throw(env, e); return (checkException()); } } return (1);}/* * Process program's flags. */staticintoptions(char** argv){ int i,j; int sz; userProperty* prop; for (i = 1; argv[i] != 0; i++) { if (argv[i][0] != '-') { break; } if (strcmp(argv[i], "-help") == 0) { usage(); exit(0); } else if (strcmp(argv[i], "-version") == 0) { printShortVersion(); exit(0); } else if (strcmp(argv[i], "-fullversion") == 0) { printFullVersion();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?