class.c

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

C
433
字号
/* * @(#)Class.c	1.127 06/10/30 * * 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.  * *//*- *      Implementation of class Class * *      former threadruntime.c, Sun Sep 22 12:09:39 1991 */#include "javavm/include/clib.h"#include "javavm/include/interpreter.h"#include "javavm/include/indirectmem.h"#include "javavm/include/common_exceptions.h"#include "generated/offsets/java_lang_Class.h"#include "jni.h"#include "jni_util.h"#include "jvm.h"#include "java_lang_Class.h"#ifdef CVM_JIT#include "javavm/include/jit/jitintrinsic.h"#endif#ifdef CVM_JAVALANGCLASS_REGISTER_NATIVES#define OBJ "Ljava/lang/Object;"#define CLS "Ljava/lang/Class;"#define STR "Ljava/lang/String;"#define JCL "Ljava/lang/ClassLoader;"#define FLD "Ljava/lang/reflect/Field;"#define MHD "Ljava/lang/reflect/Method;"#define CTR "Ljava/lang/reflect/Constructor;"#define PD  "Ljava/security/ProtectionDomain;"static JNINativeMethod methods[] = {    {"getName",          "()" STR,          (void *)&JVM_GetClassName},#ifdef JDK12    {"getSuperclass",    "()" CLS,          NULL},#else    {"getSuperclass",    "()" CLS,          (void *)&CVMjniGetSuperclass},#endif    {"getInterfaces",    "()[" CLS,         (void *)&JVM_GetClassInterfaces},    {"getClassLoader0",  "()" JCL,          (void *)&JVM_GetClassLoader},    {"getSigners",       "()[" OBJ,         (void *)&JVM_GetClassSigners},    {"setSigners",       "([" OBJ ")V",     (void *)&JVM_SetClassSigners},    {"isArray",          "()Z",             (void *)&JVM_IsArrayClass},    {"isPrimitive",      "()Z",             (void *)&JVM_IsPrimitiveClass},    {"getComponentType", "()" CLS,          (void *)&JVM_GetComponentType},    {"getModifiers",     "()I",             (void *)&JVM_GetClassModifiers},    {"getFields0",       "(I)[" FLD,        (void *)&JVM_GetClassFields},    {"getMethods0",      "(I)[" MHD,        (void *)&JVM_GetClassMethods},    {"getConstructors0", "(I)[" CTR,        (void *)&JVM_GetClassConstructors},    {"getField0",        "(" STR "I)" FLD,  (void *)&JVM_GetClassField},    {"getMethod0", "(" STR "[" CLS "I)" MHD,(void *)&JVM_GetClassMethod},    {"getConstructor0",  "([" CLS "I)" CTR, (void *)&JVM_GetClassConstructor},    {"getProtectionDomain0", "()" PD,       (void *)&JVM_GetProtectionDomain},    {"getDeclaredClasses0",  "()[" CLS,      (void *)&JVM_GetDeclaredClasses},    {"getDeclaringClass",   "()" CLS,      (void *)&JVM_GetDeclaringClass},};#undef OBJ#undef CLS#undef STR#undef JCL#undef FLD#undef MHD#undef CTR#undef PDJNIEXPORT void JNICALLJava_java_lang_Class_registerNatives(JNIEnv *env, jclass cls){#ifdef JDK12    methods[1].fnPtr = (void *)(*env)->GetSuperclass;#endif    (*env)->RegisterNatives(env, cls, methods, 			    sizeof(methods)/sizeof(JNINativeMethod));}#endif /* CVM_JAVALANGCLASS_REGISTER_NATIVES */JNIEXPORT jclass JNICALLJava_java_lang_Class_forName0(JNIEnv *env, jclass thisObj, jstring classname,			      jboolean initialize, jobject loader){    char *clname;    jclass cls = 0;    char buf[128];    int len;    int unicode_len;    if (classname == NULL) {        JNU_ThrowNullPointerException(env, 0);	return 0;    }    len = (*env)->GetStringUTFLength(env, classname);    unicode_len = (*env)->GetStringLength(env, classname);    if (len >= sizeof(buf)) {        clname = (char *)malloc(len + 1);        if (clname == NULL) {            JNU_ThrowOutOfMemoryError(env, NULL);            return NULL;        }    } else {        clname = buf;    }    (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);    if (VerifyFixClassname(clname) == JNI_TRUE) {	/* slashes present in clname, use name b4 translation for exception */	(*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);	JNU_ThrowClassNotFoundException(env, clname);	goto done;    }    if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */        JNU_ThrowClassNotFoundException(env, clname);	goto done;    }    cls = JVM_FindClassFromClassLoader(env, clname, initialize,				       loader, JNI_FALSE); done:    if (clname != buf) {	free(clname);    }    return cls;}JNIEXPORT jboolean JNICALLJava_java_lang_Class_isInstance(JNIEnv *env, jobject cls, jobject obj){    if (obj == NULL) {        return JNI_FALSE;    }    return (*env)->IsInstanceOf(env, obj, (jclass)cls);}JNIEXPORT jboolean JNICALLJava_java_lang_Class_isAssignableFrom(JNIEnv *env, jobject cls, jobject cls2){    if (cls2 == NULL) {	JNU_ThrowNullPointerException(env, 0);	return JNI_FALSE;    }    return (*env)->IsAssignableFrom(env, cls2, cls);}JNIEXPORT jclass JNICALLJava_java_lang_Class_getPrimitiveClass(JNIEnv *env,				       jclass cls,				       jstring name){    const char *utfName;    jclass result;    if (name == NULL) {	JNU_ThrowNullPointerException(env, 0);	return NULL;    }    utfName = (*env)->GetStringUTFChars(env, name, 0);    if (utfName == 0)        return NULL;    result = JVM_FindPrimitiveClass(env, utfName);    (*env)->ReleaseStringUTFChars(env, name, utfName);    return result;}#undef gcSafeRef2Class#define gcSafeRef2Class(ee, cl)	CVMgcSafeClassRef2ClassBlock(ee, cl)JNIEXPORT jboolean JNICALLJava_java_lang_Class_checkInitializedFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbInitializationDoneFlag(ee, cb);}/* * Return true if this class is currently being initialized. If me == false, * then don't return true if the class is being initialized by this thread. */JNIEXPORT jboolean JNICALLJava_java_lang_Class_checkInitializingFlag(JNIEnv *env, jclass cls, 					   jboolean me){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMExecEnv* clinitEE = CVMcbGetClinitEE(ee, cb);#if 0    /* the wince clmips compiler generates bad code for the following */    return (clinitEE != NULL) && ((clinitEE == ee) == me);#else    if (clinitEE != NULL) {	if (clinitEE == ee) {	    return me;	} else {	    return !me;	}    } else {	return CVM_FALSE;    }#endif}JNIEXPORT jboolean JNICALLJava_java_lang_Class_checkErrorFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbCheckErrorFlag(ee, cb);}JNIEXPORT void JNICALLJava_java_lang_Class_setInitializedFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMcbSetInitializationDoneFlag(ee, cb);}JNIEXPORT void JNICALLJava_java_lang_Class_setInitializingFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMcbSetClinitEE(ee, cb, ee);}JNIEXPORT void JNICALLJava_java_lang_Class_setErrorFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMcbSetErrorFlag(ee, cb);}JNIEXPORT void JNICALLJava_java_lang_Class_clearInitializingFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMcbSetClinitEE(ee, cb, NULL);}JNIEXPORT void JNICALLJava_java_lang_Class_clearSuperClassesLoadedFlag(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMcbClearRuntimeFlag(cb, ee, SUPERCLASS_LOADED);}/* some native accessor methods needed by loadSuperClasses(). */JNIEXPORT jint JNICALLJava_java_lang_Class_getClassTypeID(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbClassName(cb);}JNIEXPORT jint JNICALLJava_java_lang_Class_getSuperClassTypeID(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbSuperclassTypeID(cb);}JNIEXPORT jstring JNICALLJava_java_lang_Class_getSuperClassName(JNIEnv *env, jclass cls, jobject loader){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMClassBlock* superCb;    CVMClassTypeID cid = CVMcbSuperclassTypeID(cb);    char* cname;    jstring result;    /* See if the class is already in the loaded. If it is, then     * signal that the class doesn't need loading by returning NULL.     * This is just an optimization to avoid allocating     * the String and some unecessary loadClass() calls.     */    superCb = CVMclassLookupClassWithoutLoading(ee, cid, loader);    if (superCb != NULL) {	return NULL;    }    cname = CVMtypeidClassNameToAllocatedCString(cid);    if (cname == NULL) {	CVMthrowOutOfMemoryError(ee, NULL);	return NULL;    }        TranslateFromVMClassName(cname);    result = (*env)->NewStringUTF(env, cname);    free(cname);    return result;}JNIEXPORT jint JNICALLJava_java_lang_Class_getNumInterfaces(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbImplementsCountRaw(cb);}JNIEXPORT jint JNICALLJava_java_lang_Class_getInterfaceTypeID(JNIEnv *env, jclass cls, jint index){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbInterfaceTypeID(cb, index);}JNIEXPORT jstring JNICALLJava_java_lang_Class_getInterfaceName(JNIEnv *env, jclass cls, jint index,				      jobject loader){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMClassBlock* intfCb = gcSafeRef2Class(ee, cls);    CVMClassTypeID cid = CVMcbInterfaceTypeID(cb, index);    char* cname;    jstring result;    /* See if the class is already in the loaded. If it is, then     * signal that the class doesn't need loading by returning NULL.     * This is just an optimization to avoid allocating     * the String and some unecessary loadClass() calls.     */    intfCb = CVMclassLookupClassWithoutLoading(ee, cid, loader);    if (intfCb != NULL) {	return NULL;    }    cname = CVMtypeidClassNameToAllocatedCString(cid);    if (cname == NULL) {	CVMthrowOutOfMemoryError(ee, NULL);	return NULL;    }        TranslateFromVMClassName(cname);    result = (*env)->NewStringUTF(env, cname);    free(cname);    return result;}JNIEXPORT void JNICALLJava_java_lang_Class_linkSuperClasses(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMclassLinkSuperClasses(ee, cb);}JNIEXPORT void JNICALLJava_java_lang_Class_addToLoaderCache(JNIEnv *env, jclass cls, jobject loader){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    CVMloaderCacheAdd(ee, cb, loader); /* may throw an exception */}JNIEXPORT void JNICALLJava_java_lang_Class_notifyClassLoaded(JNIEnv *env, jclass cls){#if defined(CVM_JVMPI) || defined(CVM_JVMTI) ||   \    (defined(CVM_JIT) && defined(CVMJIT_INTRINSICS))    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);#endif /* defined(CVM_JVMPI) || defined(CVM_JVMTI) || defined(CVM_JIT) */#if defined(CVM_JIT) && defined(CVMJIT_INTRINSICS)    CVMJITintrinsicScanForIntrinsicMethods(ee, cb);#endif#ifdef CVM_JVMPI    if (CVMjvmpiEventClassLoadIsEnabled()) {	CVMjvmpiPostClassLoadEvent(ee, cb);    }#endif /* CVM_JVMPI */#ifdef CVM_JVMTI    /* Note: May change CVMisArrayOfAnyBasicType to CVMisArrayClass */    if (CVMjvmtiIsEnabled() && !CVMisArrayOfAnyBasicType(cb) &&	!CVMjvmtiClassBeingRedefined(ee, cb)) {	CVMjvmtiPostClassLoadEvent(ee, CVMcbJavaInstance(cb));    }#endif /* CVM_JVMTI */}JNIEXPORT jboolean JNICALLJava_java_lang_Class_superClassesLoaded(JNIEnv *env, jclass cls){    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    CVMClassBlock* cb = gcSafeRef2Class(ee, cls);    return CVMcbCheckRuntimeFlag(cb, SUPERCLASS_LOADED);}

⌨️ 快捷键说明

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