📄 verifier.c
字号:
/* * Get the start and end points of the * handler entry */ IPINDEX startPC = Mth_getExceptionTableStartPC(vMethod, i); IPINDEX endPC = Mth_getExceptionTableEndPC(vMethod, i); if (ip >= startPC && ip < endPC) { Vfy_throw(VE_BAD_INIT_CALL); } } vNeedInitialization = FALSE; } else { Vfy_throw(VE_EXPECT_UNINIT); } /* * Replace all the <init> receiver type with the real target type */ Vfy_ReplaceTypeWithType(receiverType, Vfy_toVerifierType(targetClassKey)); } else { /* * This is for the non INVOKESTATIC case where <init> is not being called. * * Check that an INVOKESPECIAL is either to the method being verified * or a superclass. */ if (opcode == INVOKESPECIAL && methodClassKey != Cls_getKey(vClass)) { CLASS superClass = vSuperClass; while (superClass != NULL && Cls_getKey(superClass) != methodClassKey) { superClass = Cls_getSuper(superClass); } if (superClass == NULL) { Vfy_throw(VE_INVOKESPECIAL); } } /* * Verification of access to protected methods is done here because * the superclass must be loaded at this time (other checks are * done at runtime in order to implement lazy class loading.) * * In order for the access to a protected method to be legal the * class of this method must be a direct descendant of the class * who's field is being accessed. By placing the method's class * in place of the class specified in the constant pool this * will be checked. */ if ( (opcode == INVOKESPECIAL || opcode == INVOKEVIRTUAL) && (Vfy_isProtectedMethod(vClass, methodIndex)) ) { Vfy_pop(Cls_getKey(vClass)); } else { Vfy_pop(methodClassKey); } } } /* * Push the result type. */ Vfy_pushInvokeResult(); /* * Test a few INVOKEINTERFACE things and increment the ip */ if (opcode == INVOKEINTERFACE) { if (Vfy_getUByte(ip + 3) != nwords + 1) { Vfy_throw(VE_NARGS_MISMATCH); } if (Vfy_getUByte(ip + 4) != 0) { Vfy_throw(VE_EXPECT_ZERO); } ip += 5; } else { ip += 3; } break; } case NEW: { CLASSKEY typeKey; /* * Get the pool index and check that it is a CONSTANT_Class */ POOLINDEX index = Vfy_getUShort(ip + 1); Pol_checkTagIsClass(vPool, index); /* * Get the class and check that is it not an array class */ typeKey = Pol_getClassKey(vPool, index); if (Vfy_isArrayClassKey(typeKey, 1)) { Vfy_throw(VE_EXPECT_CLASS); } /* * Convert the IP address to a VERIFIERTYPE that indicates the * result of executing a NEW */ Vfy_push(Vfy_createVerifierTypeForNewAt(ip)); /* * Mark the new instruction as existing. This is used later to check * that all the stackmap ITEM_new entries were valid. */ Vfy_markNewInstruction(ip, codeLength); /* * Advance the IP to next instruction */ ip += 3; break; } case NEWARRAY: { CLASSKEY typeKey; /* * Get the pool tag and convert it a VERIFIERTYPE */ POOLTAG tag = Vfy_getUByte(ip + 1); switch (tag) { case T_BOOLEAN: typeKey = Vfy_getBooleanArrayVerifierType(); break; case T_CHAR: typeKey = Vfy_getCharArrayVerifierType(); break;#if IMPLEMENTS_FLOAT case T_FLOAT: typeKey = Vfy_getFloatArrayVerifierType(); break; case T_DOUBLE: typeKey = Vfy_getDoubleArrayVerifierType(); break;#endif case T_BYTE: typeKey = Vfy_getByteArrayVerifierType(); break; case T_SHORT: typeKey = Vfy_getShortArrayVerifierType(); break; case T_INT: typeKey = Vfy_getIntArrayVerifierType(); break; case T_LONG: typeKey = Vfy_getLongArrayVerifierType(); break; default: Vfy_throw(VE_BAD_INSTR); break; } /* * Pop the length and push the array type */ Vfy_pop(ITEM_Integer); Vfy_push(typeKey); /* * Advance the IP to next instruction */ ip += 2; break; } case ANEWARRAY: { CLASSKEY arrayKey; VERIFIERTYPE arrayType; /* * Get the pool index and check it is CONSTANT_Class */ POOLINDEX index = Vfy_getUShort(ip + 1); Pol_checkTagIsClass(vPool, index); /* * Get the CLASSKEY */ arrayKey = Pol_getClassKey(vPool, index); /* * Convert the CLASSKEY to a VERIFIERTYPE of an array of typeKey elements */ arrayType = Vfy_getClassArrayVerifierType(arrayKey); /* * Pop the length and push the array type */ Vfy_pop(ITEM_Integer); Vfy_push(arrayType); /* * Advance the IP to next instruction */ ip += 3; break; } case ARRAYLENGTH: { /* * Pop some kind of array */ VERIFIERTYPE arrayType = Vfy_pop(Vfy_getObjectVerifierType()); /* * Check that this is an array of at least one dimension */ if (!Vfy_isArrayOrNull(arrayType)) { Vfy_throw(VE_EXPECT_ARRAY); } /* * Push the integer result and advance the IP to the next instruction */ Vfy_push(ITEM_Integer); ip += 1; break; } case CHECKCAST: { CLASSKEY typeKey; /* * Get the pool index and check it is CONSTANT_Class */ POOLINDEX index = Vfy_getUShort(ip + 1); Pol_checkTagIsClass(vPool, index); /* * Pop the type casting from and push the type casting to */ typeKey = Pol_getClassKey(vPool, index); Vfy_pop(Vfy_getObjectVerifierType()); Vfy_push(Vfy_toVerifierType(typeKey)); /* * Advance the IP to next instruction */ ip += 3; break; } case INSTANCEOF: { /* * Get the pool index and check it is CONSTANT_Class */ POOLINDEX index = Vfy_getUShort(ip + 1); Pol_checkTagIsClass(vPool, index); /* * Pop the type casting from and push a boolean (int) */ Vfy_pop(Vfy_getObjectVerifierType()); Vfy_push(ITEM_Integer); /* * Advance the IP to next instruction */ ip += 3; break; } case MONITORENTER: case MONITOREXIT: { /* * Pop some kind of object and advance the IP to next instruction */ Vfy_pop(Vfy_getObjectVerifierType()); ip++; break; } case MULTIANEWARRAY: { CLASSKEY typeKey; int dim, i; /* * Get the pool index and check it is CONSTANT_Class */ POOLINDEX index = Vfy_getUShort(ip + 1); Pol_checkTagIsClass(vPool, index); /* * Get the CLASSKEY and the number of dimensions */ typeKey = Pol_getClassKey(vPool, index); dim = Vfy_getUByte(ip + 3); /* * Check that the number of dimensions is not zero and that * the number specified in the array type is at least as great */ if (dim == 0 || !Vfy_isArrayClassKey(typeKey, dim)) { Vfy_throw(VE_MULTIANEWARRAY); } /* * Pop all the dimension sizes */ for (i = 0; i < dim; i++) { Vfy_pop(ITEM_Integer); } /* * Push the array type and advance the IP to next instruction */ Vfy_push(typeKey); ip += 4; break; } case ATHROW: { Vfy_pop(Vfy_getThrowableVerifierType()); ip++; noControlFlow = TRUE; break; } case WIDE: { SLOTINDEX index; switch (Vfy_getUByte(ip + 1)) { case IINC: { index = Vfy_getUShort(ip + 2); ip += 6; Vfy_getLocal(index, ITEM_Integer); Vfy_setLocal(index, ITEM_Integer); break; } case ILOAD: { index = Vfy_getUShort(ip + 2); ip += 4; Vfy_getLocal(index, ITEM_Integer); Vfy_push(ITEM_Integer); break; } case ALOAD: { CLASSKEY refType; index = Vfy_getUShort(ip + 2); ip += 4; refType = Vfy_getLocal(index, ITEM_Reference); Vfy_push(refType); break; } case LLOAD: { index = Vfy_getUShort(ip + 2); ip += 4; Vfy_getLocal(index, ITEM_Long); Vfy_getLocal(index + 1, ITEM_Long_2); Vfy_push(ITEM_Long); Vfy_push(ITEM_Long_2); break; } case ISTORE: { index = Vfy_getUShort(ip + 2); ip += 4; Vfy_pop(ITEM_Integer); Vfy_setLocal(index, ITEM_Integer); break; } case ASTORE: { CLASSKEY arrayElementType; index = Vfy_getUShort(ip + 2); ip += 4; arrayElementType = Vfy_pop(ITEM_Reference); Vfy_setLocal(index, arrayElementType); break; } case LSTORE: { index = Vfy_getUShort(ip + 2); ip += 4; Vfy_pop(ITEM_Long_2); Vfy_pop(ITEM_Long); Vfy_setLocal(index + 1, ITEM_Long_2); Vfy_setLocal(index, ITEM_Long); break; }#if IMPLEMENTS_FLOAT case FLOAD: { index = Vfy_getUShort(ip + 2); ip += 4; Vfy_getLocal(index, ITEM_Float); Vfy_push(ITEM_Float); break; } case DLOAD: { index = Vfy_getUShort(ip + 2); ip += 4; Vfy_getLocal(index, ITEM_Double);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -