main.c
来自「基于LWVCL开发的库」· C语言 代码 · 共 1,026 行 · 第 1/2 页
C
1,026 行
/* * main.c * Kick off program. * * Copyright (c) 1996-2000 * Transvirtual Technologies, Inc. All rights reserved. * * Copyright (c) 2006 * Kaffe.org contributors. See ChangeLog for details. * * 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 <stdlib.h>#include "config.h"#include "config-std.h"#include "config-mem.h"#include "debug.h"#include "classMethod.h"#include "jni_md.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"#if defined(KAFFE_FEEDBACK)#include "feedback.h"#endif#include "external.h"#include "kaffe_jni.h"#if defined(HAVE_GETTEXT)#include <libintl.h>#define _(T) gettext(T)#else#define _(T) (T)#endif#if defined(HAVE_LC_MESSAGES)#include <locale.h>#endif#if defined(KAFFE_PROFILER)extern int profFlag;#endif#include "jni.h"KaffeVM_Arguments vmargs;JavaVM* global_vm;static int isJar = 0;static int options(char**, int);static void usage(void);static size_t parseSize(char*);static int checkException(JNIEnv* env);static int main2(JNIEnv* env, char *argv[], int farg, int argc);#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; const char* cp; void* env;#if defined(MAIN_MD) MAIN_MD;#endif#if defined(HAVE_LC_MESSAGES) setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, "");#endif#if defined(HAVE_GETTEXT) bindtextdomain(PACKAGE, KAFFE_LOCALEDIR); textdomain(PACKAGE);#endif vmargs.version = JNI_VERSION_1_1;#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 == NULL? NULL :strdup(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 = argc - farg;#if defined(KAFFE_XPROFILER) if( xProfFlag ) { if( !enableXCallGraph() && !enableXProfiling() ) { 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(EXIT_FAILURE); } if (strcmp(argv[farg] + strlen(argv[farg]) - strlen(".class"), ".class") == 0) { fprintf(stderr, "Please do not specify the .class extension\n"); exit(EXIT_FAILURE); } /* Initialise */ if (JNI_CreateJavaVM(&global_vm, &env, &vmargs) < 0) { fprintf(stderr, "Cannot create the Java VM\n"); exit(EXIT_FAILURE); } 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 cls; jclass mcls; jmethodID mmth; jobject str; int i; int ret_code; const 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 = "org.kaffe.jar.ExecJar"; } else { exec = argv[farg]; farg++; argc--; } mcls = (*env)->FindClass(env, exec); if (checkException(env)) goto exception_happened; /* ... and run main. */ mmth = (*env)->GetStaticMethodID(env, mcls, "main", "([Ljava/lang/String;)V"); if (checkException(env)) goto exception_happened; /* Build an array of strings as the arguments */ cls = (*env)->FindClass(env, "java/lang/String"); if (checkException(env)) goto exception_happened; args = (*env)->NewObjectArray(env, argc, cls, NULL); if (checkException(env)) goto exception_happened; for (i = 0; i < argc; i++) { str = (*env)->NewStringUTF(env, argv[farg+i]); if (checkException(env)) goto exception_happened; (*env)->SetObjectArrayElement(env, args, i, str); if (checkException(env)) goto exception_happened; } /* Call method, check for errors and then exit */ (*env)->CallStaticVoidMethod(env, mcls, mmth, args); if (checkException(env)) goto exception_happened; ret_code = 0; goto done;exception_happened: ret_code = 1;done: /* We're done. We are the "main thread" and so are required to call (*vm)->DestroyJavaVM() instead of (*vm)->DetachCurrentThread() */ (*global_vm)->DestroyJavaVM(global_vm); return ret_code;}static intcheckException(JNIEnv* env){ jobject e; jclass eiic; /* Display exception stack trace */ if ((e = (*env)->ExceptionOccurred(env)) == NULL) return (0); (*env)->DeleteLocalRef(env, e); (*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(env)); } } return (1);}/* * Set a user property. * * @param propStr property to set * @return updated user properties */static userProperty*setUserProperty(char * propStr){ size_t sz; userProperty * prop; prop = malloc(sizeof(userProperty)); assert(prop != 0); prop->next = userProperties; userProperties = prop; for (sz = 0; propStr[sz] != 0; sz++) { if (propStr[sz] == '=') { propStr[sz] = 0; sz++; break; } } prop->key = propStr; prop->value = &propStr[sz]; return prop;}/* * Set AWT backend to use in Kaffe's AWT * * @param propStr AWT backend * @return updated user properties */#if defined (KAFFE_X_AWT_INCLUDED) || defined (KAFFE_QT_AWT_INCLUDED) \ || defined (KAFFE_NANOX_AWT_INCLUDED) || defined(KAFFE_XYNTH_AWT_INCLUDED)static userProperty*setKaffeAWT(const char * propStr){ char *newbootcpath; unsigned int bootcpathlength; char *prefix = DEFAULT_KAFFEHOME; const char *suffix = file_separator "kaffeawt.jar"; char *backend_property = strdup(propStr); userProperty* prop; bootcpathlength = strlen(prefix) + strlen(suffix) + strlen(path_separator) + ((vmargs.bootClasspath != NULL) ? strlen(vmargs.bootClasspath) : 0) + 1; /* Get longer buffer FIXME: free the old one */ if ((newbootcpath = malloc(bootcpathlength)) == NULL) { fprintf(stderr, "%s", _("Error: out of memory.\n")); exit(EXIT_FAILURE); } /* Construct new boot classpath */ strcpy(newbootcpath, prefix); strcat(newbootcpath, suffix); strcat(newbootcpath, path_separator); if( vmargs.bootClasspath != 0 ) { strcat(newbootcpath, vmargs.bootClasspath); } /* set the new boot classpath */ vmargs.bootClasspath = newbootcpath; /* select Xlib backend */ prop = setUserProperty(backend_property); return prop;}#endif/* * Process program's flags. */staticintoptions(char** argv, int argc){ int i; unsigned int j; size_t sz; userProperty* prop; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { break; } if (strcmp(argv[i], "-help") == 0) { usage(); exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-version") == 0) { printShortVersion(); exit(EXIT_SUCCESS); } else if (strcmp(argv[i], "-fullversion") == 0) { printFullVersion(); exit(EXIT_SUCCESS); }#if defined(__ia64__) else if (strcmp(argv[i], "-ia32") == 0) { i++; /* FIXME: skip, case handled by the calle script */ }#endif else if (strcmp(argv[i], "-classpath") == 0 || strcmp(argv[i], "-cp") == 0) { i++; if (argv[i] == 0) { fprintf(stderr, "Error: No path found for %s option.\n", argv[i - 1]); exit(EXIT_FAILURE); } /* set the new classpath */ vmargs.classpath = strdup(argv[i]); } else if (strcmp(argv[i], "-addclasspath") == 0) { char *newcpath; unsigned int cpathlength; i++; if (argv[i] == 0) { fprintf(stderr, "Error: No path found for %s option.\n", argv[i - 1]); exit(EXIT_FAILURE); } cpathlength = ((vmargs.classpath != NULL) ? strlen(vmargs.classpath) : 0) + strlen(path_separator) + strlen(argv[i]) + 1; /* Get longer buffer FIXME: free the old one */ if ((newcpath = malloc(cpathlength)) == NULL) { fprintf(stderr, "%s", _("Error: out of memory.\n")); exit(EXIT_FAILURE); } /* Construct new classpath */ if( vmargs.classpath != 0 ) strcpy(newcpath, vmargs.classpath); else newcpath[0] = '\0'; strcat(newcpath, path_separator); strcat(newcpath, argv[i]); /* set the new classpath */ vmargs.classpath = newcpath; }#ifdef KAFFE_X_AWT_INCLUDED /* Extra option to use kaffe's Xlib AWT backend. */ else if (strncmp(argv[i], "-Xkaffe-xlib-awt", (j=16)) == 0) { prop = setKaffeAWT("kaffe.awt.nativelib=xawt"); }#endif#ifdef KAFFE_QT_AWT_INCLUDED /* Extra option to use kaffe's Qt/Embedded AWT backend. */ else if (strncmp(argv[i], "-Xkaffe-qt-awt", (j=15)) == 0) { prop = setKaffeAWT("kaffe.awt.nativelib=qtawt"); }#endif#ifdef KAFFE_NANOX_AWT_INCLUDED /* Extra option to use kaffe's Nano-X AWT backend. */ else if (strncmp(argv[i], "-Xkaffe-nanox-awt", (j=17)) == 0) { prop = setKaffeAWT("kaffe.awt.nativelib=nanoxawt"); }#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?