xrun.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 285 行

C
285
字号
/* * @(#)xrun.c	1.13 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/sync.h"#include "javavm/include/globals.h"#include "javavm/include/interpreter.h"#include "javavm/include/preloader.h"#include "javavm/include/globalroots.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/stackmaps.h"#include "javavm/include/utils.h"#include "javavm/include/xrun.h"/* * Initialize or append to existing table */CVMBool CVMXrunInitTable(CVMXrunTable *table, 			 CVMInt32 numXrunArguments){    if (table->elemCnt > 0) {	CVMXrunItem* newTable;	CVMUint32 newNumArgs = table->elemCnt + numXrunArguments;		CVMassert(table->table != NULL);	newTable = (CVMXrunItem *)calloc(newNumArgs, sizeof(CVMXrunItem));	if (newTable == NULL) return CVM_FALSE;	memcpy(newTable, table->table, table->elemCnt * sizeof(CVMXrunItem));	free(table->table);	table->table = newTable;	table->elemIdx = table->elemCnt;	table->elemCnt = newNumArgs;    } else {	CVMXrunItem* newTable;	CVMassert(table->elemCnt == 0);	CVMassert(table->elemIdx == 0);	CVMassert(table->table == NULL);	newTable = (CVMXrunItem *)calloc(numXrunArguments, 					 sizeof(CVMXrunItem));	if (newTable == NULL) return CVM_FALSE;	table->table = newTable;	table->elemIdx = 0;	table->elemCnt = numXrunArguments;    }	    return CVM_TRUE;}void CVMXrunAppendToTable(CVMXrunTable *table,			  jobject libRef, JVM_OnUnload_t fptr) {    CVMassert(table->elemIdx < table->elemCnt);    table->table[table->elemIdx].shareLibRef = libRef;    table->table[table->elemIdx].onUnloadFunc = fptr;    table->elemIdx++;}/* * Call JVM_OnUnload function on each shared library. * Delete all nativeLibrary object refs.  * Free Xrun_table in CVMglobals. */void CVMXrunProcessTable(CVMXrunTable *Xrun_table, JNIEnv *env, JavaVM *vm){    CVMXrunItem *itemPtr = Xrun_table->table;    CVMInt32 i = 0;    if (Xrun_table->elemCnt == 0) {	return;    }    while (i < Xrun_table->elemCnt) {	JVM_OnUnload_t JVM_OnUnload = itemPtr[i].onUnloadFunc;	jobject libRef = itemPtr[i++].shareLibRef;	/* call JVM_OnUnload function if any */	if (JVM_OnUnload != NULL) {	    (*JVM_OnUnload)(vm);	}	/* delete native library object ref */	CVMassert(libRef != NULL);	(*env)->DeleteGlobalRef(env, libRef);     }    free(Xrun_table->table);}/* %comment: k036 *//* This takes in the entire -Xrun string and takes care of  * loading the library,  * * finding the JVM_OnUnload symbol and storing the function pointer of  * it, if any, and the loaded native library object handle in Xrun table. * * finding the JVM_Onload symbol, and calling it with the option string,  * if any, at the tail end of the argument.  * * Note that this just reuses the ClassLoader's native library loading  * code, so it automatically looks in java.library.path and  * sun.boot.library.path for the named library. */CVMBoolCVMXrunHandleArgument(CVMXrunTable* Xrun_table, JNIEnv* env, char* arg){    jclass classLoaderClass;    jclass nativeLibraryClass;    jmethodID loadLibraryInternalID;    jmethodID findID;    char* libraryNamePtr;    char* separatorPtr;    char* optionsPtr;    jstring jLibraryName = NULL;    jobject nativeLibrary = NULL;    JVM_OnLoad_t onLoadFunc;    jstring jOnLoadName = NULL;    JVM_OnUnload_t onUnloadFunc;    jstring jOnUnloadName = NULL;    JavaVM* vm;    CVMBool result = CVM_FALSE;    classLoaderClass =        CVMcbJavaInstance(CVMsystemClass(java_lang_ClassLoader));    nativeLibraryClass =        CVMcbJavaInstance(CVMsystemClass(java_lang_ClassLoader_NativeLibrary));    /* Get method IDs */    loadLibraryInternalID =	(*env)->GetStaticMethodID(env, classLoaderClass,				  "loadLibraryInternal",                                  "(Ljava/lang/Class;Ljava/lang/String;ZZ)Ljava/lang/Object;");    if (loadLibraryInternalID == NULL) {	CVMconsolePrintf("can't find method ClassLoader.loadLibraryInternal()\n");	goto done;    }    findID =	(*env)->GetMethodID(env, nativeLibraryClass,			    "find",			    "(Ljava/lang/String;)J");    if (findID == NULL) {	CVMconsolePrintf("can't find method ClassLoader$NativeLibrary.find()\n");	goto done;    }    libraryNamePtr = arg + 5;    if (*libraryNamePtr == '\0') {	CVMconsolePrintf("Missing library name\n");	goto done;    }        separatorPtr = strchr(libraryNamePtr, ':');        if (separatorPtr == NULL) {	/* No options. */	optionsPtr = NULL;	jLibraryName = (*env)->NewStringUTF(env, libraryNamePtr);    } else {	char *tmpLibraryNamePtr;	int len;	/* Have to trim options. */	optionsPtr = separatorPtr + 1;	/* Leave room for null terminator */	len = separatorPtr - libraryNamePtr + 1;	tmpLibraryNamePtr =	    malloc(len * sizeof(char));	memcpy(tmpLibraryNamePtr, libraryNamePtr, len - 1);	tmpLibraryNamePtr[len - 1] = 0;	jLibraryName = (*env)->NewStringUTF(env, tmpLibraryNamePtr);	free(tmpLibraryNamePtr);    }    if (jLibraryName == NULL) {	CVMconsolePrintf("Allocation of jLibraryName failed\n");	goto done;    }    /* Call library loading function */    nativeLibrary = (*env)->CallStaticObjectMethod(env, classLoaderClass,						   loadLibraryInternalID,                                                   NULL, jLibraryName,                                                   JNI_FALSE, JNI_TRUE);    if ((*env)->ExceptionCheck(env)) {	/* Exception already thrown, I believe */	CVMconsolePrintf("Could not find helper library for argument %s\n",			 arg);	goto done;    }    /* Look up JVM_OnLoad symbol */    jOnLoadName = (*env)->NewStringUTF(env, "JVM_OnLoad");    if (jOnLoadName == NULL) {	CVMconsolePrintf("Allocation of JVM_OnLoad String failed\n");	goto done;    }    {	jlong onloadVal =	    (*env)->CallLongMethod(env, nativeLibrary, findID, jOnLoadName);	if ((*env)->ExceptionCheck(env)) {	    CVMconsolePrintf("Could not find JVM_OnLoad of helper library "			     "for argument %s\n", arg);	    goto done;	}	onLoadFunc = (JVM_OnLoad_t)CVMlong2VoidPtr(onloadVal);    }    /* Look up JVM_OnUnload symbol     * Store away NativeLibrary object ref and function pointer for calling     * JVM_onUnload.     */    jOnUnloadName = (*env)->NewStringUTF(env, "JVM_OnUnload");    if (jOnUnloadName == NULL) {	CVMconsolePrintf("Allocation of JVM_OnUnload String failed\n");        goto done;    }    {        jlong onunloadVal =            (*env)->CallLongMethod(env, nativeLibrary, findID, jOnUnloadName);        jobject globalRef = NULL;        if ((*env)->ExceptionCheck(env)) {	    CVMconsolePrintf("Could not find JVM_OnUnload of helper library "			     "for argument %s\n", arg);            goto done;        }        globalRef = (*env)->NewGlobalRef(env, nativeLibrary);        if (globalRef == NULL) {	    CVMconsolePrintf("Allocation of global root failed\n");	    goto done;        }        onUnloadFunc = (JVM_OnUnload_t)CVMlong2VoidPtr(onunloadVal);        CVMXrunAppendToTable(Xrun_table, globalRef, onUnloadFunc);    }    /* Call JVM_OnLoad after the lookup and store away     * of JVM_OnUnload so we won't call JVM_OnUnload      * at VM shutdown if JVM_OnLoad was never called.     * This also avoid a failure after createing the globalRef,     * after adding entry to the Xrun table, and after     * calling the JVM_OnLoad function.     */    if (onLoadFunc != NULL) {        (*env)->GetJavaVM(env, &vm);        /* %comment: rt018 */        (*onLoadFunc)(vm, optionsPtr, NULL);    }    result = CVM_TRUE;    done:    (*env)->DeleteLocalRef(env, jLibraryName);    (*env)->DeleteLocalRef(env, nativeLibrary);    (*env)->DeleteLocalRef(env, jOnLoadName);    (*env)->DeleteLocalRef(env, jOnUnloadName);    return result; }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?