📄 codepreverifier.java
字号:
if (value != null && (offset == PartialEvaluator.AT_METHOD_ENTRY || livenessAnalyzer.isAliveBefore(offset, index))) { type = correspondingVerificationType(programClass, programMethod, codeAttribute, offset, value, producerValue); // Category 2 types that are alive are stored as single entries. if (value.isCategory2()) { index++; } } else { type = VerificationTypeFactory.createTopType(); } types[typeIndex++] = type; } return types; } /** * Creates and returns the verification types corresponding to the given * stack. If necessary, class constants are added to the constant pool * of the given class. */ private VerificationType[] correspondingVerificationTypes(ProgramClass programClass, ProgramMethod programMethod, CodeAttribute codeAttribute, int offset, TracedStack stack) { int maximumStackSize = stack.size(); int typeCount = 0; // Count the the number of verification types. for (int index = 0; index < maximumStackSize; index++) { // We have to work down from the top of the stack. Value value = stack.getTop(index); typeCount++; // Category 2 types are stored as single entries. if (value.isCategory2()) { index++; } } // Create and fill out the verification types. VerificationType[] types = new VerificationType[typeCount]; int typeIndex = typeCount; for (int index = 0; index < maximumStackSize; index++) { // We have to work down from the top of the stack. Value value = stack.getTop(index); Value producerValue = stack.getTopProducerValue(index); // Fill out the type. types[--typeIndex] = correspondingVerificationType(programClass, programMethod, codeAttribute, offset, value, producerValue); // Category 2 types are stored as single entries. if (value.isCategory2()) { index++; } } return types; } /** * Creates and returns the verification type corresponding to the given * value. If necessary, a class constant is added to the constant pool of * the given class. */ private VerificationType correspondingVerificationType(ProgramClass programClass, ProgramMethod programMethod, CodeAttribute codeAttribute, int offset, Value value, Value producerValue) { if (value == null) { return VerificationTypeFactory.createTopType(); } int type = value.computationalType(); switch (type) { case Value.TYPE_INSTRUCTION_OFFSET: case Value.TYPE_INTEGER: return VerificationTypeFactory.createIntegerType(); case Value.TYPE_LONG: return VerificationTypeFactory.createLongType(); case Value.TYPE_FLOAT: return VerificationTypeFactory.createFloatType(); case Value.TYPE_DOUBLE: return VerificationTypeFactory.createDoubleType(); case Value.TYPE_TOP: return VerificationTypeFactory.createTopType(); case Value.TYPE_REFERENCE: // Is it a Null type? ReferenceValue referenceValue = value.referenceValue(); if (referenceValue.isNull() == Value.ALWAYS) { return VerificationTypeFactory.createNullType(); } // Is the reference type newly created? if (offset != PartialEvaluator.AT_METHOD_ENTRY) { InstructionOffsetValue producers = producerValue.instructionOffsetValue(); if (producers.instructionOffsetCount() == 1) { int producerOffset = producers.instructionOffset(0); // Special case: in an instance initialization method, // before the super initialization, loading "this" // produces an unitinitialized stack entry. if (partialEvaluator.isInitializer() && offset <= partialEvaluator.superInitializationOffset() && producerOffset > PartialEvaluator.AT_METHOD_ENTRY && codeAttribute.code[producerOffset] == InstructionConstants.OP_ALOAD_0) { producerOffset = PartialEvaluator.AT_METHOD_ENTRY; } int initializationOffset = producerOffset == PartialEvaluator.AT_METHOD_ENTRY ? partialEvaluator.superInitializationOffset() : partialEvaluator.initializationOffset(producerOffset); if (initializationOffset != PartialEvaluator.NONE) { // Is the reference type still uninitialized? if (offset <= initializationOffset) { // It's an UninitializedThis or Uninitialized type. return producerOffset == PartialEvaluator.AT_METHOD_ENTRY ? (VerificationType)VerificationTypeFactory.createUninitializedThisType() : (VerificationType)VerificationTypeFactory.createUninitializedType(producerOffset); } } } } // It's an ordinary Object type. return VerificationTypeFactory.createObjectType(createClassConstant(programClass, referenceValue)); } throw new IllegalArgumentException("Unknown computational type ["+type+"]"); } /** * Finds or creates a class constant for the given reference value, and * returns its index in the constant pool. */ private int createClassConstant(ProgramClass programClass, ReferenceValue referenceValue) { return constantPoolEditor.addClassConstant(programClass, referenceValue.getType(), referenceValue.getReferencedClass()); } /** * Compresses the given list of full frames, for use in a stack map table. */ private void compressStackMapFrames(VerificationType[] initialVariableTypes, List stackMapFrameList) { int previousVariablesCount = initialVariableTypes.length; VerificationType[] previousVariableTypes = initialVariableTypes; int previousOffset = -1; for (int index = 0; index < stackMapFrameList.size(); index++) { FullFrame fullFrame = (FullFrame)stackMapFrameList.get(index); int variablesCount = fullFrame.variablesCount; VerificationType[] variables = fullFrame.variables; int stackCount = fullFrame.stackCount; VerificationType[] stack = fullFrame.stack; // Start computing the compressed frame. // The default is the full frame. StackMapFrame compressedFrame = fullFrame; // Are all variables equal? if (variablesCount == previousVariablesCount && equalVerificationTypes(variables, previousVariableTypes, variablesCount)) { // Are the stacks equal? //if (stackCount == previousStackCount && // equalVerificationTypes(stack, previousStack, stackCount)) //{ // // Remove the identical frame. // stackMapFrameList.remove(index--); // // // Move on to the next frame (at the same index). // continue; //} // Is the new stack empty? //else if (stackCount == 0) { compressedFrame = new SameZeroFrame(); } // Does the new stack contain a single element? else if (stackCount == 1) { compressedFrame = new SameOneFrame(stack[0]); } } // Is the stack empty? else if (stackCount == 0) { int additionalVariablesCount = variablesCount - previousVariablesCount; // Are the variables chopped? if (additionalVariablesCount < 0 && additionalVariablesCount > -4 && equalVerificationTypes(variables, previousVariableTypes, variablesCount)) { compressedFrame = new LessZeroFrame((byte)-additionalVariablesCount); } // Are the variables extended? else if (//previousVariablesCount > 0 && additionalVariablesCount > 0 && additionalVariablesCount < 4 && equalVerificationTypes(variables, previousVariableTypes, previousVariablesCount)) { // Copy the additional variables into an array. VerificationType[] additionalVariables = new VerificationType[additionalVariablesCount]; System.arraycopy(variables, variablesCount - additionalVariablesCount, additionalVariables, 0, additionalVariablesCount); compressedFrame = new MoreZeroFrame(additionalVariables); } } // Compress the instruction offset. int offset = fullFrame.u2offsetDelta; compressedFrame.u2offsetDelta = offset - previousOffset - 1; previousOffset = offset; // Remember this frame. previousVariablesCount = fullFrame.variablesCount; previousVariableTypes = fullFrame.variables; // Replace the full frame. stackMapFrameList.set(index, compressedFrame); } } /** * Returns whether the given arrays of verification types are equal, up to * the given length. */ private boolean equalVerificationTypes(VerificationType[] types1, VerificationType[] types2, int length) { if (length > 0 && (types1.length < length || types2.length < length)) { return false; } for (int index = 0; index < length; index++) { if (!types1[index].equals(types2[index])) { return false; } } return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -