📄 verify-block.c
字号:
break; default: break; } break; case LDC2W: GET_WIDX; tag = CONST_TAG(idx, pool); if (tag == CONSTANT_Long) { OPSTACK_WPUSH(getTLONG()); } else { OPSTACK_WPUSH(getTDOUBLE()); } break; /************************************************************** * INSTRUCTIONS DEALING WITH THE LOCALS AND STACK **************************************************************/ case POP: OPSTACK_POP; break; case POP2: OPSTACK_WPOP; break; #define GET_CONST_INDEX \ if (wide == true) { GET_WIDX; } \ else { GET_IDX; } /* aload_<n> takes the object reference in location <n> and pushes it onto the stack */ case ALOAD_0: idx = 0; goto ALOAD_common; case ALOAD_1: idx = 1; goto ALOAD_common; case ALOAD_2: idx = 2; goto ALOAD_common; case ALOAD_3: idx = 3; goto ALOAD_common; case ALOAD: GET_CONST_INDEX; ALOAD_common: if (!isReference(&block->locals[idx])) { DBG(VERIFY3, dprintf("%sERROR: ", indent); printType(&block->locals[idx]); dprintf("\n"); ); return verifyError(v, "aload<_n> where local variable does not contain an object reference"); } OPSTACK_PUSH(&block->locals[idx]); break; /* stores whatever's on the top of the stack in local <n> */ case ASTORE_0: idx = 0; goto ASTORE_common; case ASTORE_1: idx = 1; goto ASTORE_common; case ASTORE_2: idx = 2; goto ASTORE_common; case ASTORE_3: idx = 3; goto ASTORE_common; case ASTORE: GET_CONST_INDEX; ASTORE_common: ENSURE_OPSTACK_SIZE(1); type = getOpstackTop(block); if (!IS_ADDRESS(type) && !isReference(type)) { return verifyError(v, "astore: top of stack is not a return address or reference type"); } block->locals[idx] = *type; opstackPopBlind(block); break; /* iload_<n> takes the variable in location <n> and pushes it onto the stack */ case ILOAD_0: idx = 0; goto ILOAD_common; case ILOAD_1: idx = 1; goto ILOAD_common; case ILOAD_2: idx = 2; goto ILOAD_common; case ILOAD_3: idx = 3; goto ILOAD_common; case ILOAD: GET_CONST_INDEX; ILOAD_common: ENSURE_LOCAL_TYPE(idx, getTINT()); OPSTACK_PUSH(getTINT()); break; case ISTORE_0: idx =0; goto ISTORE_common; case ISTORE_1: idx =1; goto ISTORE_common; case ISTORE_2: idx =2; goto ISTORE_common; case ISTORE_3: idx =3; goto ISTORE_common; case ISTORE: GET_CONST_INDEX; ISTORE_common: OPSTACK_POP_T(getTINT()); block->locals[idx] = *getTINT(); break; /* fload_<n> takes the variable at location <n> and pushes it onto the stack */ case FLOAD_0: idx =0; goto FLOAD_common; case FLOAD_1: idx =1; goto FLOAD_common; case FLOAD_2: idx =2; goto FLOAD_common; case FLOAD_3: idx = 3; goto FLOAD_common; case FLOAD: GET_CONST_INDEX; FLOAD_common: ENSURE_LOCAL_TYPE(idx, getTFLOAT()); OPSTACK_PUSH(getTFLOAT()); break; /* stores a float from top of stack into local <n> */ case FSTORE_0: idx = 0; goto FSTORE_common; case FSTORE_1: idx = 1; goto FSTORE_common; case FSTORE_2: idx = 2; goto FSTORE_common; case FSTORE_3: idx = 3; goto FSTORE_common; case FSTORE: GET_CONST_INDEX; FSTORE_common: OPSTACK_POP_T(getTFLOAT()); block->locals[idx] = *getTFLOAT(); break; /* lload_<n> takes the variable at location <n> and pushes it onto the stack */ case LLOAD_0: idx = 0; goto LLOAD_common; case LLOAD_1: idx = 1; goto LLOAD_common; case LLOAD_2: idx = 2; goto LLOAD_common; case LLOAD_3: idx = 3; goto LLOAD_common; case LLOAD: GET_CONST_INDEX; LLOAD_common: ENSURE_LOCAL_WTYPE(idx, getTLONG()); OPSTACK_WPUSH(getTLONG()); break; /* lstore_<n> stores a long from top of stack into local <n> */ case LSTORE_0: idx = 0; goto LSTORE_common; case LSTORE_1: idx = 1; goto LSTORE_common; case LSTORE_2: idx = 2; goto LSTORE_common; case LSTORE_3: idx = 3; goto LSTORE_common; case LSTORE: GET_CONST_INDEX; LSTORE_common: OPSTACK_WPOP_T(getTLONG()); block->locals[idx] = *getTLONG(); block->locals[idx + 1] = *getTWIDE(); break; /* dload_<n> takes the double at local <n> and pushes it onto the stack */ case DLOAD_0: idx = 0; goto DLOAD_common; case DLOAD_1: idx = 1; goto DLOAD_common; case DLOAD_2: idx = 2; goto DLOAD_common; case DLOAD_3: idx = 3; goto DLOAD_common; case DLOAD: GET_CONST_INDEX; DLOAD_common: ENSURE_LOCAL_WTYPE(idx, getTDOUBLE()); OPSTACK_WPUSH(getTDOUBLE()); break; /* dstore stores a double from the top of stack into a local variable */ case DSTORE_0: idx = 0; goto DSTORE_common; case DSTORE_1: idx = 1; goto DSTORE_common; case DSTORE_2: idx = 2; goto DSTORE_common; case DSTORE_3: idx = 3; goto DSTORE_common; case DSTORE: GET_CONST_INDEX; DSTORE_common: OPSTACK_WPOP_T(getTDOUBLE()); block->locals[idx] = *getTDOUBLE(); block->locals[idx + 1] = *getTWIDE(); break; #undef GET_CONST_INDEX /************************************************************** * ARRAY INSTRUCTIONS! **************************************************************/ /* i put ANEWARRAY code by NEW instead of in the array instructions * section because of similarities with NEW * for creating a primitive array */ case NEWARRAY: OPSTACK_POP_T(getTINT()); /* array size */ switch(code[pc + 1]) { case TYPE_Boolean: OPSTACK_PUSH(getTBOOLARR()); break; case TYPE_Char: OPSTACK_PUSH(getTCHARARR()); break; case TYPE_Float: OPSTACK_PUSH(getTFLOATARR()); break; case TYPE_Double: OPSTACK_PUSH(getTDOUBLEARR()); break; case TYPE_Byte: OPSTACK_PUSH(getTBYTEARR()); break; case TYPE_Short: OPSTACK_PUSH(getTSHORTARR()); break; case TYPE_Int: OPSTACK_PUSH(getTINTARR()); break; case TYPE_Long: OPSTACK_PUSH(getTLONGARR()); break; default: return verifyError(v, "newarray of unknown type"); } break; case ARRAYLENGTH: ENSURE_OPSTACK_SIZE(1); type = getOpstackTop(block); if (!isArray(type)) { DBG(VERIFY3, dprintf("%stype = ", indent); printType(type); dprintf("\n"); ); return verifyError(v, "arraylength: top of operand stack is not an array"); } *type = *getTINT(); break; #define ARRAY_LOAD(_T, _ARRT) \ OPSTACK_POP_T(getTINT()); \ OPSTACK_POP_T(_ARRT); \ OPSTACK_PUSH(_T);#define ARRAY_WLOAD(_T, _ARRT) \ OPSTACK_POP_T(getTINT()); \ OPSTACK_POP_T(_ARRT); \ OPSTACK_WPUSH(_T); case AALOAD: ENSURE_OPSTACK_SIZE(2); if (getOpstackTop(block)->data.class != getTINT()->data.class) { return verifyError(v, "aaload: item on top of stack is not an integer"); } opstackPopBlind(block); type = getOpstackTop(block); if (!isArray(type)) { DBG(VERIFY3, dprintf("%serror: type = ", indent); printType(type); dprintf("\n"); ); return verifyError(v, "aaload: top of operand stack is not an array"); } if (type->tinfo & TINFO_NAME || type->tinfo & TINFO_SIG) { type->tinfo = TINFO_SIG; (type->data.sig)++; } else if (!isNull(type)) { type->tinfo = TINFO_SIG; type->data.sig = CLASS_CNAME(type->data.class) + 1; } DBG(VERIFY3, dprintf("%sarray type: ", indent); printType(type); dprintf("\n"); ); break; case IALOAD: ARRAY_LOAD(getTINT(), getTINTARR()); break; case FALOAD: ARRAY_LOAD(getTFLOAT(), getTFLOATARR()); break; case CALOAD: ARRAY_LOAD(getTINT(), getTCHARARR()); break; case SALOAD: ARRAY_LOAD(getTINT(), getTSHORTARR()); break; case LALOAD: ARRAY_WLOAD(getTLONG(), getTLONGARR()); break; case DALOAD: ARRAY_WLOAD(getTDOUBLE(), getTDOUBLEARR()); break;#undef ARRAY_LOAD#undef ARRAY_WLOAD case BALOAD: /* BALOAD can be used for bytes or booleans .... */ OPSTACK_POP_T(getTINT()); if (!typecheck (v, getTBYTEARR(), getOpstackTop(block)) && !typecheck (v, getTBOOLARR(), getOpstackTop(block))) { DBG(VERIFY3, dprintf(" OPSTACK_TOP: "); printType(getOpstackTop(block)); dprintf(" vs. what's we wanted: TBYTEARR or TBOOLARR"); ); return verifyError(v, "top of opstack does not have desired type"); } opstackPopBlind(block); OPSTACK_PUSH(getTINT()); break; case AASTORE: /* the runtime value of the type on the top of the stack must be * assignment compatible with the type of the array */ ENSURE_OPSTACK_SIZE(3); if (getOpstackItem(block, 2)->data.class != getTINT()->data.class) { return verifyError(v, "aastore: array index is not an integer"); } type = getOpstackItem(block, 1); arrayType = getOpstackItem(block, 3); DBG(VERIFY3, dprintf("%sarrayType: ", indent); printType(arrayType); dprintf(" vs. type: "); printType(type); dprintf("\n"); ); if (!isArray(arrayType)) { DBG(VERIFY3, dprintf("%serror: type = ", indent); printType(type); dprintf("\n"); ); return verifyError(v, "aastore: top of operand stack is not an array"); } if (arrayType->tinfo & TINFO_NAME || arrayType->tinfo & TINFO_SIG) { arrayType->tinfo = TINFO_SIG; (arrayType->data.sig)++; } else { if (arrayType->data.class == getTOBJARR()->data.class) { *arrayType = *getTOBJ(); } else if (!isNull(arrayType)) { arrayType->tinfo = TINFO_SIG; arrayType->data.sig = CLASS_CNAME(arrayType->data.class) + 1; } } if (!typecheck(v, arrayType, type)) { return verifyError(v, "attempting to store incompatible type in array"); } opstackPopNBlind(block, 3); break;#define ARRAY_STORE(_T, _ARRT) \ OPSTACK_POP_T(_T); \ OPSTACK_POP_T(getTINT()); \ OPSTACK_POP_T(_ARRT); #define ARRAY_WSTORE(_T, _ARRT) \ OPSTACK_WPOP_T(_T); \ OPSTACK_POP_T(getTINT()); \ OPSTACK_POP_T(_ARRT); case IASTORE: ARRAY_STORE(getTINT(), getTINTARR()); break; case FASTORE: ARRAY_STORE(getTFLOAT(), getTFLOATARR()); break; case CASTORE: ARRAY_STORE(getTINT(), getTCHARARR()); break; case SASTORE: ARRAY_STORE(getTINT(), getTSHORTARR()); break; case LASTORE: ARRAY_WSTORE(getTLONG(), getTLONGARR()); break; case DASTORE: ARRAY_WSTORE(getTDOUBLE(), getTDOUBLEARR()); break;#undef ARRAY_STORE#undef ARRAY_WSTORE case BASTORE: /* BASTORE can store either bytes or booleans .... */ OPSTACK_POP_T(getTINT()); OPSTACK_POP_T(getTINT()); if ( !typecheck(v, getTBYTEARR(), getOpstackTop(block)) && !typecheck(v, getTBOOLARR(), getOpstackTop(block))) { DBG(VERIFY3, dprintf(" OPSTACK_TOP: "); printType(getOpstackTop(block)); dprintf(" vs. what's we wanted: TBYTEARR or TBOOLARR"); ); return verifyError(v, "top of opstack does not have desired type"); } opstackPopBlind(block); break; /************************************************************** * ARITHMETIC INSTRUCTIONS **************************************************************/ case IAND: case IOR: case IXOR: case IADD: case ISUB: case IMUL: case IDIV: case IREM: case ISHL: case ISHR: case IUSHR: OPSTACK_POP_T(getTINT()); break; case INEG: OPSTACK_PEEK_T(getTINT()); break; case LAND: case LOR: case LXOR: case LADD: case LSUB: case LMUL: case LDIV: case LREM: OPSTACK_WPOP_T(getTLONG()); break; case LNEG: OPSTACK_WPEEK_T(getTLONG()); break; case LSHL: case LSHR: case LUSHR: OPSTACK_POP_T(getTINT()); OPSTACK_WPEEK_T(getTLONG()); break; case FADD: case FSUB: case FMUL: case FDIV: case FREM: OPSTACK_POP_T(getTFLOAT()); break; case FNEG: OPSTACK_PEEK_T(getTFLOAT()); break; case DADD: case DSUB: case DDIV: case DMUL: case DREM: OPSTACK_WPOP_T(getTDOUBLE()); break; case DNEG: OPSTACK_WPEEK_T(getTDOUBLE()); break; case LCMP: OPSTACK_WPOP_T(getTLONG()); OPSTACK_WPOP_T(getTLONG()); opstackPushBlind(block, getTINT()); break; case FCMPG: case FCMPL: OPSTACK_POP_T(getTFLOAT()); OPSTACK_POP_T(getTFLOAT()); opstackPushBlind(block, getTINT()); break; case DCMPG: case DCMPL: OPSTACK_WPOP_T(getTDOUBLE()); OPSTACK_WPOP_T(getTDOUBLE()); opstackPushBlind(block, getTINT()); break; case IINC: if (wide == true) { GET_WIDX; } else { GET_IDX; } ENSURE_LOCAL_TYPE(idx, getTINT()); pc = getNextPC(code, pc); if (wide == true) { pc += 2; wide = false; } continue; /************************************************************** * PRIMITIVE CONVERSION STUFF **************************************************************/ case INT2BYTE: case INT2CHAR: case INT2SHORT: OPSTACK_PEEK_T(getTINT()); break; case I2F: OPSTACK_POP_T(getTINT()); opstackPushBlind(block, getTFLOAT()); break; case I2L: OPSTACK_POP_T(getTINT()); CHECK_STACK_OVERFLOW(2); opstackWPushBlind(block, getTLONG()); break; case I2D: OPSTACK_POP_T(getTINT()); CHECK_STACK_OVERFLOW(2); opstackWPushBlind(block, getTDOUBLE()); break; case F2I: OPSTACK_POP_T(getTFLOAT()); opstackPushBlind(block, getTINT()); break; case F2L: OPSTACK_POP_T(getTFLOAT()); OPSTACK_WPUSH(getTLONG()); break; case F2D: OPSTACK_POP_T(getTFLOAT()); OPSTACK_WPUSH(getTDOUBLE()); break; case L2I: OPSTACK_WPOP_T(getTLONG()); opstackPushBlind(block, getTINT()); break; case L2F: OPSTACK_WPOP_T(getTLONG()); opstackPushBlind(block, getTFLOAT()); break; case L2D: OPSTACK_WPOP_T(getTLONG()); opstackWPushBlind(block, getTDOUBLE()); break; case D2I: OPSTACK_WPOP_T(getTDOUBLE()); opstackPushBlind(block, getTINT()); break; case D2F: OPSTACK_WPOP_T(getTDOUBLE()); opstackPushBlind(block, getTFLOAT()); break; case D2L: OPSTACK_WPOP_T(getTDOUBLE()); opstackWPushBlind(block, getTLONG()); break; /************************************************************** * OBJECT CREATION/TYPE CHECKING **************************************************************/ case INSTANCEOF: ENSURE_OPSTACK_SIZE(1); if (!isReference(getOpstackItem(block, 1))) { return verifyError(v, "instanceof: top of stack is not a reference type"); } *getOpstackTop(block) = *getTINT(); break; case CHECKCAST: ENSURE_OPSTACK_SIZE(1); opstackPopBlind(block); goto NEW_COMMON; case MULTIANEWARRAY: n = code[pc + 3]; ENSURE_OPSTACK_SIZE(n); while (n > 0) { if (getOpstackTop(block)->data.class != getTINT()->data.class) { return verifyError(v, "multinewarray: first <n> things on opstack must be integers"); } opstackPopBlind(block); n--; } goto NEW_COMMON; NEW_COMMON: GET_WIDX; CHECK_STACK_OVERFLOW(1); block->stacksz++; type = getOpstackTop(block); if (pool->tags[idx] == CONSTANT_ResolvedClass) { type->tinfo = TINFO_CLASS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -