📄 executejava_split2.c
字号:
TRACE(("\ti2b => %d\n", STACK_INT(-1))); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0); CASE(opc_i2c) STACK_INT(-1) = CVMint2Char(STACK_INT(-1)); TRACE(("\ti2c => %d\n", STACK_INT(-1))); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0); CASE(opc_i2s) STACK_INT(-1) = CVMint2Short(STACK_INT(-1)); TRACE(("\ti2s => %d\n", STACK_INT(-1))); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0); COMPARISON_OP_WITHZERO(lt, <); COMPARISON_OP_WITHZERO(gt, >); COMPARISON_OP_WITHZERO(le, <=); COMPARISON_OP_WITHZERO(ge, >=); COMPARISON_OP_INTS(lt, <); COMPARISON_OP_INTS(gt, >); COMPARISON_OP_INTS(le, <=); COMPARISON_OP_INTS(ge, >=); COMPARISON_OP_WITHZERO(eq, ==); COMPARISON_OP_WITHZERO(ne, !=); COMPARISON_OP_INTS(eq, ==); COMPARISON_OP_INTS(ne, !=); COMPARISON_OP_REFS(eq, ==); /* include ref comparison */ COMPARISON_OP_REFS(ne, !=); /* include ref comparison */ NULL_COMPARISON_OP(null, !!); NULL_COMPARISON_OP(nonnull, !); CASE(opc_return) { /* * Offer a GC-safe point. The current frame is always up * to date, so don't worry about de-caching frame. */ if (CHECK_PENDING_REQUESTS(ee)) { goto handle_pending_request; } CACHE_PREV_TOS(frame); TRACE(("\treturn\n")); goto handleReturn; } CASE_NT(opc_ireturn) CASE_NT(opc_freturn) CASE(opc_areturn) { CVMJavaVal32 result; /* * Offer a GC-safe point. The current frame is always up * to date, so don't worry about de-caching frame. */ if (CHECK_PENDING_REQUESTS(ee)) { goto handle_pending_request; } result = STACK_INFO(-1); CACHE_PREV_TOS(frame); STACK_INFO(0) = result; topOfStack++; TRACEIF(opc_ireturn, ("\tireturn %d\n", STACK_INT(-1))); TRACEIF(opc_areturn, ("\tareturn 0x%x\n", STACK_OBJECT(-1))); TRACEIF(opc_freturn, ("\tfreturn %f\n", STACK_FLOAT(-1))); goto handleReturn; } CASE_NT(opc_agetstatic_quick) CASE(opc_getstatic_quick) { CVMFieldBlock* fb = CVMcpGetFb(cp, GET_INDEX(pc+1)); JVMTI_WATCHING_FIELD_ACCESS(NULL) STACK_INFO(0) = CVMfbStaticField(ee, fb); TRACE(("\t%s #%d %C.%F[%d] (0x%X) ==>\n", CVMopnames[*pc], GET_INDEX(pc+1), CVMfbClassBlock(fb), fb, CVMfbOffset(fb), STACK_INT(0))); UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); } CASE_NT(opc_aputstatic_quick) CASE(opc_putstatic_quick) { CVMFieldBlock* fb = CVMcpGetFb(cp, GET_INDEX(pc+1)); JVMTI_WATCHING_FIELD_MODIFICATION(NULL, CVM_FALSE, CVMfbIsRef(fb)); CVMfbStaticField(ee, fb) = STACK_INFO(-1); TRACE(("\t%s #%d (0x%X) ==> %C.%F[%d]\n", CVMopnames[*pc], GET_INDEX(pc+1), STACK_INT(-1), CVMfbClassBlock(fb), fb, CVMfbOffset(fb))); UPDATE_PC_AND_TOS_AND_CONTINUE(3, -1); } /* Quick static field access for romized classes with initializers. */ CASE_NT(opc_agetstatic_checkinit_quick) CASE_NT(opc_getstatic_checkinit_quick) { CVMFieldBlock* fb = CVMcpGetFb(cp, GET_INDEX(pc+1)); CVMClassBlock* cb = CVMfbClassBlock(fb); INIT_CLASS_IF_NEEDED(ee, cb); JVMTI_WATCHING_FIELD_ACCESS(NULL) STACK_INFO(0) = CVMfbStaticField(ee, fb); TRACE(("\t%s #%d %C.%F[%d] (0x%X) ==>\n", CVMopnames[*pc], GET_INDEX(pc+1), cb, fb, CVMfbOffset(fb), STACK_INT(0))); UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); } CASE_NT(opc_aputstatic_checkinit_quick) CASE_NT(opc_putstatic_checkinit_quick) { CVMFieldBlock* fb = CVMcpGetFb(cp, GET_INDEX(pc+1)); CVMClassBlock* cb = CVMfbClassBlock(fb); INIT_CLASS_IF_NEEDED(ee, cb); JVMTI_WATCHING_FIELD_MODIFICATION(NULL, CVM_FALSE, CVMfbIsRef(fb)); CVMfbStaticField(ee, fb) = STACK_INFO(-1); TRACE(("\t%s #%d (0x%X) ==> %C.%F[%d]\n", CVMopnames[*pc], GET_INDEX(pc+1), STACK_INT(-1), cb, fb, CVMfbOffset(fb))); UPDATE_PC_AND_TOS_AND_CONTINUE(3, -1); } CASE(opc_iaload) ARRAY_LOADTO32(Int, "%d", STACK_INT); CASE(opc_faload) ARRAY_LOADTO32(Float, "%f", STACK_FLOAT); CASE(opc_aaload) ARRAY_LOADTO32(Ref, "0x%x", STACK_OBJECT); CASE(opc_baload) ARRAY_LOADTO32(Byte, "%d", STACK_INT); CASE(opc_caload) ARRAY_LOADTO32(Char, "%d", STACK_INT); CASE(opc_saload) ARRAY_LOADTO32(Short, "%d", STACK_INT); CASE(opc_iastore) ARRAY_STOREFROM32(Int, "%d", STACK_INT); CASE(opc_fastore) ARRAY_STOREFROM32(Float, "%f", STACK_FLOAT); /* * This one looks different because of the assignability check */ CASE(opc_aastore) { CVMObject* rhsObject = STACK_OBJECT(-1); ARRAY_INTRO(Ref, -3); if (rhsObject != 0) { /* Check assignability of rhsObject into arrObj */ CVMClassBlock* elemType = CVMarrayElementCb(CVMobjectGetClass(arrObj)); CVMClassBlock* rhsType = CVMobjectGetClass(rhsObject); if (rhsType != elemType) { /* Try a quick check first */ if (!CVMisAssignable(ee, rhsType, elemType)) { if (!CVMlocalExceptionOccurred(ee)) { goto throwArrayStoreException; } else { /* When C StackOverflowError is thrown */ goto handle_exception; } } } } CVMD_arrayWriteRef(arrObj, index, rhsObject); TRACE(("\t%s 0x%x ==> %O[%d] ==>\n", CVMopnames[*pc], rhsObject, arrObj, index)); UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); } CASE(opc_bastore) ARRAY_STOREFROM32(Byte, "%d", STACK_INT); CASE(opc_castore) ARRAY_STOREFROM32(Char, "%d", STACK_INT); CASE(opc_sastore) ARRAY_STOREFROM32(Short, "%d", STACK_INT); CASE(opc_arraylength) { CVMArrayOfAnyType* arrObj = (CVMArrayOfAnyType*)STACK_OBJECT(-1); CHECK_NULL(arrObj); STACK_INT(-1) = CVMD_arrayGetLength(arrObj); TRACE(("\t%s %O.length(%d) ==>\n", CVMopnames[*pc], arrObj, STACK_INT(-1))); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0); } /* Throw an exception. */ CASE(opc_athrow) { CVMObject* directObj = STACK_OBJECT(-1); CHECK_NULL(directObj); TRACE(("\tathrow => %O\n", directObj)); DECACHE_PC(frame); /* required for handle_exception */ CVMgcUnsafeThrowLocalException(ee, directObj); goto handle_exception; } /* monitorenter and monitorexit for locking/unlocking an object */ /* goto and jsr. They are exactly the same except jsr pushes * the address of the next instruction first. */ CASE(opc_jsr) { CVMInt16 offset = CVMgetInt16(pc + 1); /* push return address on the stack */ STACK_ADDR(0) = pc + 3; TRACE(("\t%s %#x (offset=%d)\n",CVMopnames[*pc], pc + offset, offset)); UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_GC_CHECK(offset, 1); } CASE(opc_goto) { CVMInt16 offset = CVMgetInt16(pc + 1); TRACE(("\t%s %#x (offset=%d)\n",CVMopnames[*pc], pc + offset, offset)); /* %comment h002 */ UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_BACKWARDS_CHECK(offset, 0); } /* Allocate memory for a new java object. */ CASE_NT(opc_new_checkinit_quick) { CVMClassBlock* cb = CVMcpGetCb(cp, GET_INDEX(pc + 1)); INIT_CLASS_IF_NEEDED(ee, cb); /* Fall through */ } CASE(opc_new_quick) { CVMObject* directObj; CVMClassBlock* cb = CVMcpGetCb(cp, GET_INDEX(pc + 1)); /* * CVMgcAllocNewInstance may block and initiate GC, so we must * de-cache our state for GC first. */ DECACHE_PC(frame); DECACHE_TOS(frame); directObj = CVMgcAllocNewInstance(ee, cb); if (directObj == NULL) { goto throwOutOfMemoryError; } CVMID_icellSetDirect(ee, &STACK_ICELL(0), directObj); TRACE(("\tnew_quick %C => 0x%x\n", cb, directObj)); UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); } CASE(opc_invokenonvirtual_quick) { CVMObject* directObj; CVMUint32 mbIndex = GET_INDEX(pc + 1); DECACHE_TOS(frame); /* must include arguments for proper gc */ mb = CVMcpGetMb(cp, mbIndex); topOfStack -= CVMmbArgsSize(mb); directObj = STACK_OBJECT(0); CHECK_NULL(directObj); goto callJavaMethod; } /* invoke a virtual method of java/lang/Object */ /* * NOTE: we can get rid of opc_invokevirtualobject_quick now because * arrays have their own methodTablePtr (they just use Object's * methodTablePtr), and CVMobjMethodTableSlot() has been optimized * to no longer check if it's dealing with an array type, so we * could just as well use opc_invokevirtual_quick. */ CASE(opc_invokevirtualobject_quick) { CVMObject* directObj; DECACHE_TOS(frame); /* must include arguments for proper gc */ topOfStack -= pc[2]; directObj = STACK_OBJECT(0); CHECK_NULL(directObj); mb = CVMobjMethodTableSlot(directObj, pc[1]); goto callJavaMethod; } /* invoke a virtual method */ CASE_NT(opc_invokevirtual_quick) CASE_NT(opc_ainvokevirtual_quick) CASE_NT(opc_dinvokevirtual_quick) CASE(opc_vinvokevirtual_quick) { CVMObject* directObj; CVMClassBlock* ocb; CVMInt32 argsAdjust; CVMUint32 methodIndex; CVMMethodBlock** methodTablePtr; argsAdjust = -pc[2]; /* Quick! */ methodIndex = pc[1]; /* Quick! */ DECACHE_TOS(frame); /* must include arguments for proper gc */ directObj = STACK_OBJECT(argsAdjust); DECACHE_PC(frame); CHECK_NULL(directObj); ocb = CVMobjectGetClass(directObj); methodTablePtr = CVMcbMethodTablePtr(ocb); mb = methodTablePtr[methodIndex]; topOfStack += argsAdjust; goto callJavaMethod; } /* invoke a virtual method */ CASE(opc_invokevirtual_quick_w) { CVMObject* directObj; CVMClassBlock* ocb; CVMInt32 argsAdjust; CVMUint32 methodIndex; CVMMethodBlock** methodTablePtr; mb = CVMcpGetMb(cp, GET_INDEX(pc + 1)); DECACHE_TOS(frame); /* must include arguments for proper gc */ argsAdjust = -CVMmbArgsSize(mb); /* Quick! */ methodIndex = CVMmbMethodTableIndex(mb); /* Quick! */ directObj = STACK_OBJECT(argsAdjust); DECACHE_PC(frame); CHECK_NULL(directObj); ocb = CVMobjectGetClass(directObj); methodTablePtr = CVMcbMethodTablePtr(ocb); mb = methodTablePtr[methodIndex]; topOfStack += argsAdjust; goto callJavaMethod; } /* invoke an interface method */ CASE(opc_invokeinterface_quick) { CVMObject* directObj; CVMMethodBlock* imb; /* interface mb for method we are calling */ CVMClassBlock* icb; /* interface cb for method we are calling */ CVMClassBlock* ocb; /* cb of the object */ CVMUint32 interfaceCount; CVMInterfaces* objectIntfs; CVMInterfaceTable* itablePtr; CVMUint16 methodTableIndex;/* index into ocb's methodTable */ int guess = pc[4]; imb = CVMcpGetMb(cp, GET_INDEX(pc + 1)); DECACHE_TOS(frame); /* must include arguments for proper gc */ /* don't use pc[3] because transtion mb's don't set it up */ topOfStack -= CVMmbArgsSize(imb); icb = CVMmbClassBlock(imb); directObj = STACK_OBJECT(0); CHECK_NULL(directObj); ocb = CVMobjectGetClass(directObj); objectIntfs = CVMcbInterfaces(ocb); interfaceCount = CVMcbInterfaceCountGivenInterfaces(objectIntfs); itablePtr = CVMcbInterfaceItable(objectIntfs); /* * Search the objects interface table, looking for the entry * whose interface cb matches the cb of the inteface we * are invoking. */ if (guess < 0 || guess >= interfaceCount || CVMcbInterfacecbGivenItable(itablePtr, guess) != icb) { CVMBool containerNotInROM = !CVMisROMPureCode(CVMmbClassBlock(frame->mb)); guess = interfaceCount - 1; while ((guess >= 0) && (CVMcbInterfacecbGivenItable(itablePtr,guess) != icb)) { guess--; } if (guess >= 0) { CVMassert(CVMcbInterfacecbGivenItable(itablePtr, guess) == icb); /* Update the guess if it was wrong, the code is not * for a romized class, and the code is not transition * code, which is also in ROM. */ CVMassert(!CVMframeIsTransition(frame)); if (containerNotInROM) pc[4] = guess; } } if (guess >= 0) { /* * We know CVMcbInterfacecb(ocb, guess) is for the interface that * we are invoking. Use it to convert the index of the method in * the interface's methods array to the index of the method * in the class' methodTable array. */ methodTableIndex = CVMcbInterfaceMethodTableIndexGivenInterfaces( objectIntfs, guess, CVMmbMethodSlotIndex(imb)); } else if (icb == CVMsystemClass(jav
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -