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 + -
显示快捷键?