jvm.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,294 行 · 第 1/5 页
C
2,294 行
/* * 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. * *//* Implement jvm.h functions here, unless they more suitably belong * to somewhere else. */#include "javavm/export/jvm.h"#include "javavm/export/jni.h"#include "native/common/jni_util.h"#include "javavm/include/interpreter.h"#include "javavm/include/gc_common.h"#include "javavm/include/porting/threads.h"#include "javavm/include/porting/time.h"#include "javavm/include/porting/int.h"#include "javavm/include/porting/doubleword.h"#include "javavm/include/clib.h"#include "javavm/include/indirectmem.h"#include "javavm/include/globalroots.h"#include "javavm/include/localroots.h"#include "javavm/include/preloader.h"#include "javavm/include/common_exceptions.h"#include "generated/offsets/java_lang_Class.h"#include "generated/offsets/java_lang_Thread.h"#include "generated/offsets/java_lang_Throwable.h"#ifndef CDC_10#include "javavm/include/javaAssertions.h"#include "generated/offsets/java_lang_StackTraceElement.h"#endif#include "generated/javavm/include/build_defs.h"#ifdef CVM_JVMTI#include "javavm/include/jvmtiExport.h"#endif#ifdef CVM_JVMPI#include "javavm/include/jvmpi_impl.h"#endif#ifdef CVM_REFLECT# include "javavm/include/reflect.h"#endif#ifdef CVM_DYNAMIC_LINKING# include "javavm/include/porting/linker.h"#endif#ifdef CVM_JIT#include "javavm/include/jit_common.h"#endif#ifdef JAVASE#include "javavm/include/se_init.h"#endifJNIEXPORT jint JNICALLJVM_GetInterfaceVersion(void){ return JVM_INTERFACE_VERSION;}JNIEXPORT jint JNICALLJVM_GetLastErrorString(char *buf, int len){ return CVMioGetLastErrorString(buf, len);}/* * Find primitive classes */JNIEXPORT jclass JNICALLJVM_FindPrimitiveClass(JNIEnv *env, const char *utf){ CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassTypeID tid; CVMClassBlock* cb; /* * We need to use the "new" function, because the "lookup" function * is only valid when we know that the type already exists. */ tid = CVMtypeidNewClassID(ee, utf, (int)strlen(utf)); if (tid == CVM_TYPEID_ERROR) { /* CVMtypeidNewClassID() will always succeed if the type already * exist, so it must not be primitive. */ CVMclearLocalException(ee); return NULL; } cb = CVMpreloaderLookupPrimitiveClassFromType(tid); CVMtypeidDisposeClassID(ee, tid); if (cb != NULL) { return (*env)->NewLocalRef(env, CVMcbJavaInstance(cb)); } else { return NULL; }}/* * Link the class */JNIEXPORT void JNICALLJVM_ResolveClass(JNIEnv *env, jclass cls){#ifdef CVM_CLASSLOADING CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(CVMjniEnv2ExecEnv(env), cls); CVMclassLink(CVMjniEnv2ExecEnv(env), cb, CVM_FALSE);#else return; /* the class must be romized and is therefore linked */#endif}JNIEXPORT jclass JNICALLJVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init, jobject loader, jboolean throwError){ CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassBlock* cb = CVMclassLookupByNameFromClassLoader(ee, name, init, loader, NULL, throwError); if (cb != NULL) { return (*env)->NewLocalRef(env, CVMcbJavaInstance(cb)); } return NULL;}JNIEXPORT jclass JNICALLJVM_DefineClass(JNIEnv *env, const char *name, jobject loaderRef, const jbyte *buf, jsize bufLen, jobject pd){ CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); return CVMdefineClass(ee, name, loaderRef, (CVMUint8*)buf, bufLen, pd, CVM_FALSE);}/* * Reflection support functions */JNIEXPORT jstring JNICALLJVM_GetClassName(JNIEnv* env, jclass cls){ /* Try to avoid 1 malloc */ char buf[128]; char* className = buf; /* Consider caching the classname String with the class. */ CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(CVMjniEnv2ExecEnv(env), cls); jobject res; if (!CVMtypeidClassNameToCString(CVMcbClassName(cb), buf, 128)) { className = CVMtypeidClassNameToAllocatedCString(CVMcbClassName(cb)); } TranslateFromVMClassName(className); res = (*env)->NewLocalRef(env, (*env)->NewStringUTF(env, className)); if (className != buf) free(className); return res;}JNIEXPORT jobjectArray JNICALLJVM_GetClassInterfaces(JNIEnv *env, jclass cls){#ifdef CVM_REFLECT CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); jobject obj = CVMjniCreateLocalRef(ee); if (obj == NULL) { /* exception thrown */ return NULL; } CVMreflectInterfaces(ee, CVMgcSafeClassRef2ClassBlock(ee, cls), (CVMArrayOfRefICell*) obj); if (CVMexceptionOccurred(ee)) { CVMjniDeleteLocalRef(env, obj); return NULL; } return obj;#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(CVMjniEnv2ExecEnv(env), NULL); return NULL;#endif /* CVM_REFLECT */}JNIEXPORT jobject JNICALLJVM_GetClassLoader(JNIEnv *env, jclass cls){#ifdef CVM_CLASSLOADING CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(ee, cls); return (*env)->NewLocalRef(env, CVMcbClassLoader(cb));#else return NULL;#endif}JNIEXPORT jboolean JNICALLJVM_IsInterface(JNIEnv *env, jclass cls){ CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(CVMjniEnv2ExecEnv(env), cls); return CVMcbIs(cb, INTERFACE);}#ifdef JDK12/* * Get the class's signers, if any. Make sure to return a new array, * not the original. Returning the original is a security hole as * the caller could modify it. */JNIEXPORT jobjectArray JNICALLJVM_GetClassSigners(JNIEnv *env, jclass cls){ Hjava_lang_Class *cb = (Hjava_lang_Class *)DeRef(env, cls); HArrayOfObject *copy, *orig; HObject **copy_data, **orig_data; int i; size_t n; orig = (HArrayOfObject *) unhand(cb)->signers; if (orig == NULL) return NULL; n = obj_length(orig); copy = (HArrayOfObject *)ArrayAlloc(T_CLASS, n); if (copy == NULL) { ThrowOutOfMemoryError(CVMjniEnv2ExecEnv(env), 0); return NULL; } copy_data = (HObject **) unhand(copy)->body; orig_data = (HObject **) unhand(orig)->body; /* Use i <= n, NOT i < n, to get copy_data[n] which contains the type of objects in the array */ for (i=0; i <= n; i++) { copy_data[i] = orig_data[i]; } KEEP_POINTER_ALIVE(copy_data); KEEP_POINTER_ALIVE(orig_data); return MkRefLocal(env, copy);}JNIEXPORT void JNICALLJVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers){ ClassClass *cb = (ClassClass *)DeRef(env, cls); unhand(cb)->signers = (HArrayOfObject *)DeRef(env, signers);}#endifJNIEXPORT jobject JNICALLJVM_GetProtectionDomain(JNIEnv *env, jclass cls){#ifdef CVM_CLASSLOADING CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassBlock* cb; cb = CVMgcSafeClassRef2ClassBlock(ee, cls); return (*env)->NewLocalRef(env, CVMcbProtectionDomain(cb));#else return NULL;#endif}#ifdef CVM_HAVE_DEPRECATEDJNIEXPORT void JNICALLJVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject pd){#ifdef CVM_CLASSLOADING CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(ee, cls); /* Allocate a global root for the protection domain if necessary. */ if (CVMcbProtectionDomain(cb) == NULL) { CVMcbProtectionDomain(cb) = CVMID_getProtectionDomainGlobalRoot(ee); if (CVMcbProtectionDomain(cb) == NULL) { CVMthrowOutOfMemoryError(ee, NULL); return; } } CVMID_icellAssign(ee, CVMcbProtectionDomain(cb), pd);#endif}#endifJNIEXPORT jboolean JNICALLJVM_IsArrayClass(JNIEnv *env, jclass cls){ CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(CVMjniEnv2ExecEnv(env), cls); return CVMisArrayClass(cb);}JNIEXPORT jboolean JNICALLJVM_IsPrimitiveClass(JNIEnv *env, jclass cls){ CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(CVMjniEnv2ExecEnv(env), cls); return CVMcbIs(cb, PRIMITIVE);}JNIEXPORT jclass JNICALLJVM_GetComponentType(JNIEnv *env, jclass cls){ CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(ee, cls); CVMClassBlock* elementCb; if (!CVMisArrayClass(cb)) { return NULL; } elementCb = CVMarrayElementCb(cb); CVMassert(elementCb != NULL); return (*env)->NewLocalRef(env, CVMcbJavaInstance(elementCb));}/* Remember that ACC_SUPER is added by the VM, and must be stripped. */JNIEXPORT jint JNICALLJVM_GetClassModifiers(JNIEnv *env, jclass cls){ CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); CVMClassBlock* cb = CVMgcSafeClassRef2ClassBlock(ee, cls); CVMUint32 icount = CVMcbInnerClassesInfoCount(cb); /* Check if this class happens to be a member class. */ if (icount != 0) { CVMUint32 i; CVMClassTypeID classID = CVM_TYPEID_ERROR; for (i = 0; i < icount; i++) { CVMConstantPool* cp = CVMcbConstantPool(cb); CVMUint16 classIdx = CVMcbInnerClassInfo(cb, i)->innerClassIndex; CVMClassBlock* innerCb;#ifdef CVM_CLASSLOADING if (CVMcpCheckResolvedAndGetTID(ee, cb, cp, classIdx, &classID)) { innerCb = CVMcpGetCb(cp, classIdx); } else { innerCb = NULL; }#else innerCb = CVMcpGetCb(cp, classIdx);#endif if (cb == innerCb || CVMcbClassName(cb) == classID) { /* Aha, this is really a member class. */ jint access = CVMcbInnerClassInfo(cb, i)->innerClassAccessFlags; /* Unlike CVMcbAccessFlags(), these access flags are * not modifed so they will fit in one bytes. Therefore, * no translation is necessary. */ return (access & (~JVM_ACC_SUPER)); } } } /* If we get here, then the class is not a member class. */ /* The implementation of JVM_GetClassModifiers() needs to conform to the specification of Class.getModifiers(). Acording to that spec, the only bits of relevance to this method are public, final, interface, and abstract. The spec also mentioned private, protected, and static but those don't exist in the VM spec for class access flags. */ { jint access = CVMcbAccessFlags(cb); CVMassert(JVM_ACC_PUBLIC == CVM_CLASS_ACC_PUBLIC); CVMassert(JVM_ACC_FINAL == CVM_CLASS_ACC_FINAL); CVMassert(JVM_ACC_INTERFACE == CVM_CLASS_ACC_INTERFACE); CVMassert(JVM_ACC_ABSTRACT == CVM_CLASS_ACC_ABSTRACT); access &= (JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_INTERFACE | JVM_ACC_ABSTRACT); return access; }}/* * NOTE: The following routines are conditionally compiled. These can * not simply be removed from the build, since java.lang.Class refers * to them and we don't have JavaFilter incorporated yet. Therefore * they fail by calling CVMthrowUnsupportedOperationException when * reflection is not configured in. * JVM_GetClassFields * JVM_GetClassMethods * JVM_GetClassConstructors * JVM_GetClassField * JVM_GetClassMethod * JVM_GetClassConstructor * JVM_GetDeclaredClasses * JVM_GetDeclaringClass */JNIEXPORT jobjectArray JNICALLJVM_GetClassFields(JNIEnv *env, jclass cls, jint which){#ifdef CVM_REFLECT CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); jobject obj = CVMjniCreateLocalRef(ee); if (obj == NULL) /* exception thrown */ return NULL; CVMreflectFields(ee, CVMgcSafeClassRef2ClassBlock(ee, cls), which, (CVMArrayOfRefICell*) obj); if (CVMexceptionOccurred(ee)) { CVMjniDeleteLocalRef(env, obj); return NULL; } return obj;#else /* CVM_REFLECT */ CVMthrowUnsupportedOperationException(CVMjniEnv2ExecEnv(env), NULL); return NULL;#endif /* CVM_REFLECT */}JNIEXPORT jobjectArray JNICALLJVM_GetClassMethods(JNIEnv *env, jclass cls, jint which){#ifdef CVM_REFLECT CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); jobject obj = CVMjniCreateLocalRef(ee); if (obj == NULL) /* exception thrown */ return NULL; CVMreflectMethods(ee, CVMgcSafeClassRef2ClassBlock(ee, cls), which, (CVMArrayOfRefICell*) obj); if (CVMexceptionOccurred(ee)) { CVMjniDeleteLocalRef(env, obj);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?