jvm.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,294 行 · 第 1/5 页
C
2,294 行
lineno = -1;#endif } CVMD_arrayWriteInt(pcArray, count, (CVMJavaInt) ((lineno << 16) | (CVMmbMethodIndex(mb) & 0xffff))); /* Write the class object into the backtrace array. */ { CVMClassICell* classICell = CVMcbJavaInstance(CVMmbClassBlock(mb)); CVMD_arrayWriteRef(backtrace, count + 2, CVMID_icellDirect(ee, classICell)); } count++; } CVMassert(count + 2 == CVMD_arrayGetLength(backtrace));#endif}#ifndef CDC_10static CVMInt32 CVMgetStackTraceDepth(CVMExecEnv *ee, CVMThrowableICell* throwableICell){#ifdef CVM_DEBUG_STACKTRACES CVMInt32 stackDepth = 0; if (CVMID_icellIsNull(throwableICell)) { CVMthrowNullPointerException(ee, NULL); return 0; } CVMID_localrootBegin(ee) { CVMID_localrootDeclare(CVMObjectICell, backtraceICell); CVMID_fieldReadRef(ee, throwableICell, CVMoffsetOfjava_lang_Throwable_backtrace, backtraceICell); if (!CVMID_icellIsNull(backtraceICell)) { CVMID_arrayGetLength(ee, (CVMArrayOfRefICell*)backtraceICell, stackDepth); /* The first two elements of the backtrace array are pcValue * array and isCompiled array. So need to subtract the size * by 2 */ stackDepth -= 2; } } CVMID_localrootEnd(); return stackDepth;#else return 0;#endif}JNIEXPORT jint JNICALLJVM_GetStackTraceDepth(JNIEnv *env, jobject throwable) { CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); return CVMgetStackTraceDepth(ee, throwable);}#ifdef CVM_DEBUG_STACKTRACESstatic CVMObjectICell* CVMgetStackTraceElement(CVMExecEnv *ee, CVMThrowableICell* throwableICell, CVMInt32 index){ CVMObjectICell* stElementICell; CVMJavaInt backtraceLen; CVMJavaInt linenoInfo, lineno; CVMClassBlock* cb; CVMMethodBlock* mb; CVMMethodTypeID tid; char buf[256]; const char* fn; const CVMClassBlock* stackTraceElementCb; CVMJavaBoolean isCompiled = CVM_FALSE; if (CVMID_icellIsNull(throwableICell)) { CVMthrowNullPointerException(ee, NULL); return NULL; } stElementICell = CVMjniCreateLocalRef(ee); CVMID_localrootBegin(ee) { CVMID_localrootDeclare(CVMArrayOfRefICell, backtraceICell);#ifdef CVM_JIT CVMID_localrootDeclare(CVMArrayOfBooleanICell, isCompiledArrayICell);#endif CVMID_localrootDeclare(CVMArrayOfIntICell, pcArrayICell); CVMID_localrootDeclare(CVMObjectICell, tempICell); CVMID_localrootDeclare(CVMStringICell, stringICell); /* Get the backtrace array field of the throwable */ CVMID_fieldReadRef(ee, throwableICell, CVMoffsetOfjava_lang_Throwable_backtrace, tempICell); CVMID_icellAssign(ee, backtraceICell, (CVMArrayOfRefICell*)tempICell); if (CVMID_icellIsNull(backtraceICell)) { goto failed_goto_localRootEnd; } CVMID_arrayGetLength(ee, backtraceICell, backtraceLen); if (index >= backtraceLen - 2) { CVMthrowArrayIndexOutOfBoundsException(ee, NULL); goto failed_goto_localRootEnd; } /* Now allocate a new java.lang.StackTraceElement object */ stackTraceElementCb = CVMsystemClass(java_lang_StackTraceElement); CVMID_allocNewInstance(ee, (CVMClassBlock*)stackTraceElementCb, stElementICell); if (CVMID_icellIsNull(stElementICell)) { CVMthrowOutOfMemoryError(ee, NULL); goto failed_goto_localRootEnd; } /* The first element of the backtrace array is an array of * method index and lineno info: * * lineno << 16 | methodIndex * */ CVMID_arrayReadRef(ee, backtraceICell, 0, tempICell); CVMID_icellAssign(ee, pcArrayICell, (CVMArrayOfIntICell*)tempICell); if (CVMID_icellIsNull(pcArrayICell)) { goto failed_goto_localRootEnd; } CVMID_arrayReadInt(ee, pcArrayICell, index, linenoInfo);#ifdef CVM_JIT /* The 2nd element of the backtrace array is an array of * isCompiled values. */ CVMID_arrayReadRef(ee, backtraceICell, 1, tempICell); CVMID_icellAssign(ee, isCompiledArrayICell, (CVMArrayOfBooleanICell*)tempICell); if (CVMID_icellIsNull(isCompiledArrayICell)) { goto failed_goto_localRootEnd; } CVMID_arrayReadBoolean(ee, isCompiledArrayICell, index, isCompiled);#endif /* Get the indexed backtrace element. It's java.lang.Class * object. */ CVMID_arrayReadRef(ee, backtraceICell, index+2, tempICell); if (CVMID_icellIsNull(tempICell)) { goto failed_goto_localRootEnd; } cb = CVMgcSafeClassRef2ClassBlock(ee, tempICell); mb = CVMcbMethodSlot(cb, ((CVMUint32)linenoInfo & 0xffff)); lineno = linenoInfo >> 16; tid = CVMmbNameAndTypeID(mb); /* Fill in the fields */ /* Fill in the declaringClass field */ CVMclassname2String(CVMcbClassName(cb), buf, sizeof(buf)); CVMnewStringUTF(ee, stringICell, buf); CVMID_fieldWriteRef(ee, stElementICell, CVMoffsetOfjava_lang_StackTraceElement_declaringClass, stringICell); /* Fill in the methodName field */ CVMtypeidMethodNameToCString(tid, buf, sizeof(buf)); CVMnewStringUTF(ee, stringICell, buf); CVMID_fieldWriteRef(ee, stElementICell, CVMoffsetOfjava_lang_StackTraceElement_methodName, stringICell); /* Fill in the fileName field */ fn = getSourceFileName(cb); if (fn != NULL) { CVMnewStringUTF(ee, stringICell, fn); CVMID_fieldWriteRef(ee, stElementICell, CVMoffsetOfjava_lang_StackTraceElement_fileName, stringICell); } /* Fill in the lineNumber field */ CVMID_fieldWriteInt(ee, stElementICell, CVMoffsetOfjava_lang_StackTraceElement_lineNumber, lineno); /* Fill in the isCompiled field */ CVMID_fieldWriteInt(ee, stElementICell, CVMoffsetOfjava_lang_StackTraceElement_isCompiled, isCompiled);#ifdef CVM_DEBUG /* Fill in the methodSignature field for debug builds. For non-debug * leave the field as null. */ CVMtypeidMethodTypeToCString(tid, buf, sizeof(buf)); CVMnewStringUTF(ee, stringICell, buf); CVMID_fieldWriteRef(ee, stElementICell, CVMoffsetOfjava_lang_StackTraceElement_methodSignature, stringICell);#endiffailed_goto_localRootEnd:; } CVMID_localrootEnd(); return stElementICell;}#endifJNIEXPORT jobject JNICALLJVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index) {#ifdef CVM_DEBUG_STACKTRACES CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); return (jobject)CVMgetStackTraceElement(ee, throwable, (CVMInt32)index);#else return NULL;#endif}#endif /* !CDC_10 *//* Called from object.c */JNIEXPORT jint JNICALLJVM_IHashCode(JNIEnv *env, jobject obj){ if (obj == NULL) { return 0; } return CVMobjectGetHashSafe(CVMjniEnv2ExecEnv(env), obj);}JNIEXPORT void JNICALLJVM_MonitorWait(JNIEnv *env, jobject obj, jlong millis){ CVMExecEnv *ee = CVMjniEnv2ExecEnv(env); if (CVMlongLtz(millis)) { CVMthrowIllegalArgumentException(ee, "timeout value is negative"); return; }#ifdef CVM_JVMPI if (CVMjvmpiEventMonitorWaitIsEnabled()) { CVMjvmpiPostMonitorWaitEvent(ee, obj, millis); }#endif#ifdef CVM_JVMTI ee->threadState = CVM_THREAD_WAITING | CVM_THREAD_OBJECT_WAIT; ee->threadState |= (millis == 0 ? CVM_THREAD_WAITING_INDEFINITE : CVM_THREAD_WAITING_TIMEOUT); if (CVMjvmtiShouldPostMonitorWait()) { CVMjvmtiPostMonitorWaitEvent(ee, obj, millis); }#endif /* NOTE: CVMgcSafeObjectWait() may throw certain exceptions: */ CVMgcSafeObjectWait(ee, obj, millis);#ifdef CVM_JVMPI if (CVMjvmpiEventMonitorWaitedIsEnabled()) { CVMjvmpiPostMonitorWaitedEvent(ee, obj); }#endif#ifdef CVM_JVMTI if (CVMjvmtiShouldPostMonitorWaited()) { CVMjvmtiPostMonitorWaitedEvent(ee, obj, CVM_FALSE); }#endif}JNIEXPORT void JNICALLJVM_MonitorNotify(JNIEnv *env, jobject obj){ CVMExecEnv *ee = CVMjniEnv2ExecEnv(env);#ifdef CVM_JVMTI ee->threadState &= ~(CVM_THREAD_WAITING | CVM_THREAD_WAITING_INDEFINITE | CVM_THREAD_WAITING_TIMEOUT);#endif /* NOTE: CVMgcSafeObjectNotify() may throw certain exceptions: */ CVMgcSafeObjectNotify(ee, obj);}JNIEXPORT void JNICALLJVM_MonitorNotifyAll(JNIEnv *env, jobject obj){ CVMExecEnv *ee = CVMjniEnv2ExecEnv(env);#ifdef CVM_JVMTI CVMsysMutexLock(ee, &CVMglobals.threadLock); CVM_WALK_ALL_THREADS(ee, currentEE, { CVMassert(CVMcurrentThreadICell(currentEE) != NULL); if (!CVMID_icellIsNull(CVMcurrentThreadICell(currentEE))) { currentEE->threadState &= ~(CVM_THREAD_WAITING | CVM_THREAD_WAITING_INDEFINITE | CVM_THREAD_WAITING_TIMEOUT); } }); CVMsysMutexUnlock(ee, &CVMglobals.threadLock);#endif /* NOTE: CVMgcSafeObjectNotifyAll() may throw certain exceptions: */ CVMgcSafeObjectNotifyAll(ee, obj);}JNIEXPORT jobject JNICALLJVM_Clone(JNIEnv *env, jobject obj){ CVMClassBlock* cb; CVMExecEnv* ee = CVMjniEnv2ExecEnv(env); jobject result; CVMID_localrootBegin(ee) { CVMID_localrootDeclare(CVMObjectICell, cloneObj); CVMID_objectGetClass(ee, obj, cb); /* * Now let's see whether we are cloning an array or an object */ if (CVMisArrayClass(cb)) { CVMArrayOfAnyTypeICell* arrObj = (CVMArrayOfAnyTypeICell*)obj; CVMBasicType typeCode = CVMarrayElemTypeCode(cb); CVMJavaInt arrLen; CVMID_arrayGetLength(ee, arrObj, arrLen); /* Make the copy first */ CVMID_allocNewArray(ee, typeCode, cb, arrLen, cloneObj); if (CVMID_icellIsNull(cloneObj)) { /* Allocation failed */ result = NULL; CVMthrowOutOfMemoryError(ee, "cloning array object"); goto bailOut; } JVM_ArrayCopy(env, NULL, obj, 0, cloneObj, 0, arrLen); } else { if (!CVMimplementsInterface(ee, cb, CVMsystemClass(java_lang_Cloneable))) { result = NULL; if (!CVMlocalExceptionOccurred(ee)) { CVMthrowCloneNotSupportedException(ee, "cloning regular object"); } goto bailOut; } CVMID_allocNewInstance(ee, cb, cloneObj); if (CVMID_icellIsNull(cloneObj)) { /* Allocation failed */ result = NULL; CVMthrowOutOfMemoryError(ee, "cloning regular object"); goto bailOut; } CVMD_gcUnsafeExec(ee, { CVMObject* srcObj = CVMID_icellDirect(ee, obj); CVMObject* dstObj = CVMID_icellDirect(ee, cloneObj); CVMClassBlock* cbp; CVMwithAssertsOnly( CVMUint32 coveredSize = sizeof(CVMObjectHeader); ); /* * Walk all instance fields in superclass order, * and copy each with the right CVMD_ call. */ for (cbp = cb; cbp != NULL; cbp = CVMcbSuperclass(cbp)) { CVMUint32 i; /* * Go through the declared fields */ for (i = 0; i < CVMcbFieldCount(cbp); i++) { CVMFieldBlock* fb = CVMcbFieldSlot(cbp, i); if (!CVMfbIs(fb, STATIC)) { CVMUint32 offset = CVMfbOffset(fb); CVMClassTypeID type = CVMtypeidGetType(CVMfbNameAndTypeID(fb)); switch (type) { case CVM_TYPEID_INT: case CVM_TYPEID_SHORT: case CVM_TYPEID_CHAR: case CVM_TYPEID_BYTE: case CVM_TYPEID_BOOLEAN: { CVMJavaInt elem; CVMD_fieldReadInt(srcObj, offset, elem); CVMD_fieldWriteInt(dstObj, offset, elem); CVMwithAssertsOnly( coveredSize += sizeof(CVMJavaInt); ); break; } case CVM_TYPEID_LONG: { CVMJavaLong l; CVMD_fieldReadLong(srcObj, offset, l); CVMD_fieldWriteLong(dstObj, offset, l); CVMwithAssertsOnly( coveredSize += sizeof(CVMJavaLong); ); break; } case CVM_TYPEID_DOUBLE: { CVMJavaDouble d; CVMD_fieldReadDouble(srcObj, offset, d); CVMD_fieldWriteDouble(dstObj, offset, d); CVMwithAssertsOnly( coveredSize += sizeof(CVMJavaDouble); ); break; } case CVM_TYPEID_FLOAT: { CVMJavaFloat f; CVMD_fieldReadFloat(srcObj, offset, f); CVMD_fieldWriteFloat(dstObj, offset, f); CVMwithAssertsOnly( coveredSize += sizeof(CVMJavaFloat); ); break; } default: /* Must be a ref */ { CVMObject* o; CVMD_fieldReadRef(srcObj, offset, o); CVMD_fieldWriteRef(dstObj, offset, o); CVMwithAssertsOnly( coveredSize += sizeof(CVMObject*); ); break; } } } } } /* * Now make sure that we have copied just the right * number of bytes from one object to the other */ /* * NOTE: the assert makes only sense if all the sizeof() above * are multiples of CVMJavaVal32. * For a 64 bit port this might not make sense. * Leave the assert in for now, until a 64-bit port makes * us modify it. */ CVMassert(coveredSize == CVMcbInstanceSize(cb)); }); } result = (*env)->NewLocalRef(env, cloneObj); bailOut:; } CVMID_localrootEnd(); return result;}/* * Thread class calls */typedef struct { void (*nativeFunc)(void *); void *nativeFuncArg;} CVMNativeRunInfo;#ifdef CVM_DEBUG_ASSERTSenum { NATIVERUNINFO_UNDEFINED = 0, NATIVERUNINFO_THREAD_START_INFO, NATIVERUNINFO_NATIVE_RUN_INFO,};#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?