void LoadExpr (unsigned Flags, struct ExprDesc* Expr) /* Load an expression into the primary register if it is not already there. */ { if (ED_IsLVal (Expr)) { /* Dereferenced lvalue. If this is a bit field its type is unsigned. * But if the field is completely contained in the lower byte, we will * throw away the high byte anyway and may therefore load just the * low byte. */ if (ED_IsBitField (Expr)) { Flags |= (Expr->BitOffs + Expr->BitWidth <= CHAR_BITS)? CF_CHAR : CF_INT; Flags |= CF_UNSIGNED; } else { Flags |= TypeOf (Expr->Type); } if (ED_NeedsTest (Expr)) { Flags |= CF_TEST; } switch (ED_GetLoc (Expr)) { case E_LOC_ABS: /* Absolute: numeric address or const */ g_getstatic (Flags | CF_ABSOLUTE, Expr->IVal, 0); break; case E_LOC_GLOBAL: /* Global variable */ g_getstatic (Flags | CF_EXTERNAL, Expr->Name, Expr->IVal); break; case E_LOC_STATIC: case E_LOC_LITERAL: /* Static variable or literal in the literal pool */ g_getstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal); break; case E_LOC_REGISTER: /* Register variable */ g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal); break; case E_LOC_STACK: /* Value on the stack */ g_getlocal (Flags, Expr->IVal); break; case E_LOC_PRIMARY: /* The primary register - just test if necessary */ if (Flags & CF_TEST) { g_test (Flags); } break; case E_LOC_EXPR: /* Reference to address in primary with offset in Expr */ g_getind (Flags, Expr->IVal); break; default: Internal ("Invalid location in LoadExpr: 0x%04X", ED_GetLoc (Expr)); } /* Handle bit fields. The actual type may have been casted or * converted, so be sure to always use unsigned ints for the * operations. */ if (ED_IsBitField (Expr)) { unsigned F = CF_INT | CF_UNSIGNED | CF_CONST | (Flags & CF_TEST); /* Shift right by the bit offset */ g_asr (F, Expr->BitOffs); /* And by the width if the field doesn't end on an int boundary */ if (Expr->BitOffs + Expr->BitWidth != CHAR_BITS && Expr->BitOffs + Expr->BitWidth != INT_BITS) { g_and (F, (0x0001U << Expr->BitWidth) - 1U); } } /* Expression was tested */ ED_TestDone (Expr); } else { /* An rvalue */ if (ED_IsLocExpr (Expr)) { if (Expr->IVal != 0) { /* We have an expression in the primary plus a constant * offset. Adjust the value in the primary accordingly. */ Flags |= TypeOf (Expr->Type); g_inc (Flags | CF_CONST, Expr->IVal); } } else { /* Constant of some sort, load it into the primary */ LoadConstant (Flags, Expr); } /* Are we testing this value? */ if (ED_NeedsTest (Expr)) { /* Yes, force a test */ Flags |= TypeOf (Expr->Type); g_test (Flags); ED_TestDone (Expr); } } }
u4 ExecutionEngine::Execute(Frame* pFrameStack) { //ASSERT(pFrameStack); Frame* pFrame=&pFrameStack[0]; //ASSERT(pFrame); u1 *bc=pFrame->pMethod->pCode_attr->code + pFrame->pc; i4 error=0; JavaClass *pClass = pFrame->pClass; QString strMethod; pClass->GetStringFromConstPool(pFrame->pMethod->name_index, strMethod); i4 index=0; qint64 longVal; while(1) { switch(bc[pFrame->pc]) { case nop: pFrame->pc++; break; ///////////////// Stack Operations //////////////// //Instructions that push a constant onto the stack case iconst_m1: case iconst_0: case iconst_1: case iconst_2: case iconst_3: case iconst_4: case iconst_5: pFrame->sp++; pFrame->stack[pFrame->sp].intValue = (u1)bc[pFrame->pc]-iconst_0; pFrame->pc++; break; case aconst_null: pFrame->sp++; pFrame->stack[pFrame->sp].object.index = 0; pFrame->pc++; break; case lconst_0:// 9 /*(0x9)*/ case lconst_1:// 10 /*(0xa)*/ pFrame->sp++; pFrame->stack[pFrame->sp].intValue=0; pFrame->sp++; pFrame->stack[pFrame->sp].intValue=(u1)bc[pFrame->pc]-lconst_0; pFrame->pc++; break; case bipush:// 16 /*(0x10)*/ pFrame->sp++; pFrame->stack[pFrame->sp].charValue=(u1)bc[pFrame->pc+1]; pFrame->pc+=2; break; case sipush:// 17 /*(0x11)*/ pFrame->sp++; pFrame->stack[pFrame->sp].shortValue=getu2(&bc[pFrame->pc+1]); pFrame->pc+=3; break; case ldc: //Push item from constant pool pFrame->stack[++pFrame->sp] =LoadConstant(pFrame->pClass, (u1)bc[pFrame->pc+1]); pFrame->pc+=2; break; case ldc2_w:// 20 /*(0x14)*/ index=getu2(&bc[pFrame->pc+1]); pFrame->sp++; pFrame->stack[pFrame->sp].intValue = getu4(&((char *)pClass->constant_pool[index])[1]); pFrame->sp++; pFrame->stack[pFrame->sp].intValue = getu4(&((char *)pClass->constant_pool[index])[5]); pFrame->pc += 3; break; //Instructions that load a local variable onto the stack case aload:// 25 /*(0x19)*/ pFrame->sp++; pFrame->stack[pFrame->sp]=pFrame->stack[(u1)bc[pFrame->pc+1]]; pFrame->pc+=2; break; case iload:// 21 /*(0x15)*/ pFrame->sp++; pFrame->stack[pFrame->sp] = pFrame->stack[(u1)bc[pFrame->pc+1]]; pFrame->pc+=2; break; case iload_0: //26 Load int from local variable 0 case iload_1: //27 Load int from local variable 1 case iload_2: //28 Load int from local variable 2 case iload_3: //29 Load int from local variable 3 pFrame->sp++; pFrame->stack[pFrame->sp] = pFrame->stack[(u1)bc[pFrame->pc]-iload_0]; pFrame->pc++; break; case lload:// 22 /*(0x16)*/ break; case lload_0:// 30 /*(0x1e) */ case lload_1:// 31 /*(0x1f) */ case lload_2:// 32 /*(0x20) */ case lload_3:// 33 /*(0x21) */ pFrame->sp++; pFrame->stack[pFrame->sp]=pFrame->stack[(u1)bc[pFrame->pc]-lload_0]; pFrame->sp++; pFrame->stack[pFrame->sp]=pFrame->stack[(u1)bc[pFrame->pc]-lload_0+1]; pFrame->pc++; break; case fload_0: // 34 /*(0x22)*/ case fload_1: // 35 /*(0x23) */ case fload_2: // 36 /*(0x24) */ case fload_3: // 37 /*(0x25)*/ pFrame->sp++; pFrame->stack[pFrame->sp] = pFrame->stack[(u1)bc[pFrame->pc]-fload_0]; pFrame->pc++; break; case aload_0: //42 Load reference from local variable 0 case aload_1: //Load reference from local variable 1 case aload_2: //Load reference from local variable 2 case aload_3: //Load reference from local variable 3 pFrame->sp++; pFrame->stack[pFrame->sp]= pFrame->stack[(u1)bc[pFrame->pc]-aload_0]; DumpObject(pFrame->stack[pFrame->sp].object); pFrame->pc++; break; case iaload:// 46 /*(0x2e)*/Load int from array //..., arrayref, index => ..., value pFrame->stack[pFrame->sp-1]=pObjectHeap->GetObjectPointer(pFrame->stack[pFrame->sp-1].object)[pFrame->stack[pFrame->sp].intValue+1]; pFrame->sp--; pFrame->pc++; break; case aaload://50 //..., arrayref, index ..., value pFrame->stack[pFrame->sp-1]=pObjectHeap->GetObjectPointer(pFrame->stack[pFrame->sp-1].object)[pFrame->stack[pFrame->sp].intValue+1]; pFrame->sp--; pFrame->pc++; break; //Instructions that store a value from the stack into a local variable case astore:// 58 (0x3a) pFrame->stack[(u1)bc[pFrame->pc+1]]=pFrame->stack[pFrame->sp--]; pFrame->pc+=2; break; case istore:// 54 /*(0x36)*/ pFrame->stack[(u1)bc[pFrame->pc+1]]=pFrame->stack[pFrame->sp--]; pFrame->pc+=2; break; case istore_0: // 59 /*(0x3b)*/ case istore_1: // 60 /*(0x3c) */ case istore_2: // 61 /*(0x3d) */ case istore_3: // 62 /*(0x3e)*/ pFrame->stack[(u1)bc[pFrame->pc]-istore_0]=pFrame->stack[pFrame->sp--]; pFrame->pc++; break; case lstore_0: // 63 /*(0x3f) */ case lstore_1: // 64 /*(0x40) */ case lstore_2: // 65 /*(0x41) */ case lstore_3: // 66 /*(0x42) */ pFrame->stack[(u1)bc[pFrame->pc]-lstore_0+1]=pFrame->stack[pFrame->sp--]; pFrame->stack[(u1)bc[pFrame->pc]-lstore_0]=pFrame->stack[pFrame->sp--]; pFrame->pc++; break; case fstore_0: case fstore_1: case fstore_2: case fstore_3: pFrame->stack[(u1)bc[pFrame->pc]-fstore_0]=pFrame->stack[pFrame->sp--]; pFrame->pc++; break; case astore_0:// 75 /*(0x4b) Store reference into local variable 0*/ case astore_1:// 76 /*(0x4c) */ case astore_2:// 77 /*(0x4d) */ case astore_3:// 78 /*(0x4e)*/ pFrame->stack[(u1)bc[pFrame->pc]-astore_0]=pFrame->stack[pFrame->sp--]; pFrame->pc++; break; case iastore:// 79 /*(0x4f)*/ case aastore: // 83 - both seems same (TODO: Check it) pObjectHeap->GetObjectPointer(pFrame->stack[pFrame->sp-2].object)[pFrame->stack[pFrame->sp-1].intValue+1]=pFrame->stack[pFrame->sp]; pFrame->sp-=3; pFrame->pc++; break; //Generic (typeless) stack operations case dup:// 89 /*(0x59)*/ pFrame->stack[pFrame->sp+1]=pFrame->stack[pFrame->sp]; pFrame->sp++; pFrame->pc++; break; case dup_x1:// 90 /*(0x5a)*/ pFrame->stack[pFrame->sp+1]=pFrame->stack[pFrame->sp]; pFrame->stack[pFrame->sp]=pFrame->stack[pFrame->sp-1]; pFrame->stack[pFrame->sp-1]=pFrame->stack[pFrame->sp+1]; pFrame->sp++; pFrame->pc++; break; case dup_x2:// 91 /*(0x5b)*/ error=1; break; //Type Conversion //Integer Arithmetic case iadd: //96 pFrame->stack[pFrame->sp-1].intValue=pFrame->stack[pFrame->sp-1].intValue + pFrame->stack[pFrame->sp].intValue; pFrame->sp--; pFrame->pc++; break; case ladd:// 97 /*(0x61)*/ longVal = (qint64)(((qint64)pFrame->stack[pFrame->sp-3].intValue<<32) | (qint64)pFrame->stack[pFrame->sp-2].intValue)+(qint64)(((qint64)pFrame->stack[pFrame->sp-1].intValue<<32) | (qint64)pFrame->stack[pFrame->sp].intValue); pFrame->stack[pFrame->sp-3].intValue=HIINT64(longVal); pFrame->stack[pFrame->sp-2].intValue=LOINT64(longVal); pFrame->sp -= 2; pFrame->pc++; break; case isub: //100 pFrame->stack[pFrame->sp-1].intValue=pFrame->stack[pFrame->sp-1].intValue - pFrame->stack[pFrame->sp].intValue; pFrame->sp--; pFrame->pc++; break; case imul://104 pFrame->stack[pFrame->sp-1].intValue=pFrame->stack[pFrame->sp-1].intValue * pFrame->stack[pFrame->sp].intValue; pFrame->sp--; pFrame->pc++; break; case iinc:// 132 /*(0x84)*/ Increment local variable by constant pFrame->stack[(u1)bc[pFrame->pc+1]].intValue += (char)bc[pFrame->pc+2]; pFrame->pc+=3; break; ////////////////////// Logic /////////////////// //Shift operations //Bitwise boolean operations //Floating Point Arithmetic /////////////// Objects and Arrays //////////// //Instructions that deal with objects case _new:// 187 (0xbb) ExecuteNew(pFrame); pFrame->pc+=3; break; case putfield: //181 (0xb5): Set field in object PutField(pFrame); pFrame->sp-=2; pFrame->pc+=3; break; case getfield: //180 (0xb4) Fetch field from object GetField(pFrame); pFrame->pc+=3; break; //Instructions that deal with arrays case newarray:// 188 /*(0xbc)*/ ExecuteNewArray(pFrame); pFrame->pc+=2; break; case anewarray: //189 ExecuteANewArray(pFrame); pFrame->pc+=3; break; ////////////// Control Flow ///////////////////// //Conditional branch instructions case if_icmpeq: // 159 /*(0x9f) */ if(pFrame->stack[pFrame->sp -1].intValue == pFrame->stack[pFrame->sp].intValue) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp-=2; break; case if_icmpne: //160 /*(0xa0) */ if(pFrame->stack[pFrame->sp -1].intValue != pFrame->stack[pFrame->sp].intValue) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp-=2; break; case if_icmplt: // 161 /*(0xa1) */ if(pFrame->stack[pFrame->sp -1].intValue < pFrame->stack[pFrame->sp].intValue) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp-=2; break; case if_icmpge: // 162 /*(0xa2) */ if(pFrame->stack[pFrame->sp -1].intValue >= pFrame->stack[pFrame->sp].intValue) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp-=2; break; case if_icmpgt: // 163 /*(0xa3) */ if(pFrame->stack[pFrame->sp -1].intValue > pFrame->stack[pFrame->sp].intValue) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp-=2; break; case if_icmple: // 164 /*(0xa4)*/ if(pFrame->stack[pFrame->sp -1].intValue <= pFrame->stack[pFrame->sp].intValue) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp-=2; break; case ifeq:// 153 /*(0x99) */ if(pFrame->stack[pFrame->sp].intValue == 0) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp--; break; case ifne:// 154 /*(0x9a) */ if(pFrame->stack[pFrame->sp].intValue != 0) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp--; break; case iflt:// 155 /*(0x9b) */ if(pFrame->stack[pFrame->sp].intValue < 0) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp--; break; case ifge:// 156 /*(0x9c) */ if(pFrame->stack[pFrame->sp].intValue >= 0) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp--; break; case ifgt:// 157 /*(0x9d) */ if(pFrame->stack[pFrame->sp].intValue > 0) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp--; break; case ifle:// 158 /*(0x9e)*/ if(pFrame->stack[pFrame->sp].intValue <= 0) { pFrame->pc+= geti2(&bc[pFrame->pc+1]); } else { pFrame->pc+=3; } pFrame->sp--; break; //Comparison instructions //Unconditional branch instructions case _goto: // 167 /*(0xa7)*/ pFrame->pc += geti2(&bc[pFrame->pc+1]); break; //Table jumping instructions ////////////// Exceptions /////////////////////// case athrow: error =1; break; //////////////////////// Method Invocation and Return //////// //Method invocation instructions case invokespecial: ExecuteInvokeSpecial(pFrame); pFrame->pc+=3; break; case invokevirtual: //182 ExecuteInvokeVirtual(pFrame, invokevirtual); pFrame->pc+=3; break; case invokestatic:// 184 ExecuteInvokeVirtual(pFrame, invokestatic); pFrame->pc+=3; break; //Method return instructions case ireturn: //172 (0xac) pFrame->stack[0].intValue=pFrame->stack[pFrame->sp].intValue; return ireturn; break; case _return: //177 (0xb1): Return (void) from method return 0;//METHOD_RETURN; break; //////////////// Thread Synchronization //////////////////// case monitorenter:// Enter and acquire object monitor case monitorexit:// Release and exit object monitor error = 1; break; default: error=1; break; } if(error) break; } //ASSERT(!error); return 0; }