classinitialize.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 197 行
C
197 行
/* * @(#)classinitialize.c 1.50 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/interpreter.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/preloader.h"#include "javavm/export/jni.h"static intCVMprivateClassInit(CVMExecEnv* ee, CVMClassBlock* cb, CVMMethodBlock **p_mb);/* * Perform the class initialization as described in the VM spec, * 2nd Edition (2.17.5). Link the class if necessary. * * This is the public version that will use JNI to call * Class.runStaticInitializers. */CVMBoolCVMclassInit(CVMExecEnv* ee, CVMClassBlock* cb){ CVMBool res = (CVMprivateClassInit(ee, cb, 0) == 0); if (res == CVM_TRUE) { /* Only try to resolve the cp entries if the * initialization succeeded. */ CVMcpResolveCbEntriesWithoutClassLoading(ee, cb); } return res;}/* * Perform the class initialization as described in the VM spec, * 2nd Edition (2.17.5). Link the class if necessary. * * This is the version that interpreter loop will use to intialize * classes. It avoids C recursion by not using JNI to invoke * Class.runStaticInitializers. Instead it munges the interpreter * state so that upon return the interperer will start executiong * in Class.runStaticInitializers. */intCVMclassInitNoCRecursion(CVMExecEnv* ee, CVMClassBlock* cb, CVMMethodBlock **p_mb){ int res = CVMprivateClassInit(ee, cb, p_mb); if (res != -1) { /* Only try to resolve the cp entries if the * initialization succeeded. */ CVMcpResolveCbEntriesWithoutClassLoading(ee, cb); } return res;}/* * Perform the class initialization as described in the VM spec, * 2nd Edition (2.17.5). Link the class if necessary. * * This version supports both CVMclassInit and CVMclassInitNoCRecursion. * If p_mb == 0, then is uses JNI to invoke Class.runStaticInitializers. * * If p_mb != 0 then it avoids C recursion by pushing a transition * frame that knows how to invoke Class.runStaticInitializers and then * munges the interpreter state so that upon return the interpeter * starts executing at the beginning of Class.runStaticInitializers. * * We could have avoided the transition frame and just setup a JavaFrame * for Class.runStaticInitializers, but this would require some * extra logic in handle_return, which would slow down all method returns. * * Please note that in one case Class.runStaticInitializers is actually * invoked from here and in other caes the interpreter state is modified * so that upon return the interpreter will start executing * Class.runStaticInitializers. * * RESULT if p_mb != NULL: * 0 - No action taken. Class is already initialized. * 1 - Transition frame successfully pushed. * -1 - An error occured. Exception was thrown. * * RESULT if p_mb == NULL: * 0 - Initialization successful or class is already initialized * -1 - An error occured. Exception was thrown. */static intCVMprivateClassInit(CVMExecEnv* ee, CVMClassBlock* cb, CVMMethodBlock **p_mb){ if (!CVMcbInitializationNeeded(cb, ee)) { /* nothing to do */ return 0; } CVMtraceClinit(("[InitClass() called for %C]\n", cb)); CVMassert(CVMD_isgcSafe(ee)); /* Don't need to initialize or verify primitive or array classes */ if (CVMcbIs(cb, PRIMITIVE) || CVMisArrayClass(cb)) { CVMcbSetInitializationDoneFlag(ee, cb); return 0; } else { /* Get the mb for Class.runStaticInitializers. */ CVMMethodBlock* mb = CVMglobals.java_lang_Class_runStaticInitializers;#ifdef CVM_CLASSLOADING /* * Link the class hierarchy. */ if (!CVMclassLink(ee, cb, CVM_FALSE)) { return -1; }#endif if (!CVMcbHasStaticsOrClinit(cb)) { /* If this class doesn't have a static initializer, then we're done. * * WARNING: It is not safe to do this until after the LINKED flag * has been set. But the LINKED flag should be set by now. */ CVMassert(CVMcbCheckRuntimeFlag(cb, LINKED)); CVMcbSetInitializationDoneFlag(ee, cb); return 0; } if (p_mb != NULL) { CVMBool success = CVM_TRUE; /* * We need to do the special invocation of runStaticInitializers * that avoids C recursion. This section of code must run gcUnsafe * because of the stack manipulation it does. */ CVMD_gcUnsafeExec(ee, { CVMFrame* frame = (CVMFrame *)CVMpushTransitionFrame(ee, mb); if (frame != NULL) { /* Push Class object of the class that we want to run * static initializers on. */ CVMID_icellAssignDirect(ee, &frame->topOfStack->j.r, CVMcbJavaInstance(cb)); ++frame->topOfStack; *p_mb = mb; } else { success = CVM_FALSE; /* exception already thrown */ } }); return success ? 1 : -1; } else { /* This is a normal invocation of runStaticInitializers that * just uses JNI to enter the interpreter. */ JNIEnv* env = CVMexecEnv2JniEnv(ee); int retVal; /* Call Class.runStaticInitializers. We need to disable remote * exceptions during this call, since we will be executing * java code that we don't want to abort if a remote * exception occurrs. */ CVMdisableRemoteExceptions(ee); (*env)->CallVoidMethod(env, CVMcbJavaInstance(cb), mb); if (CVMlocalExceptionOccurred(ee)) { retVal = -1; } else { retVal = 0; } CVMenableRemoteExceptions(ee); return retVal; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?