in src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java [428:528]
public void unpack() throws Pack200Exception {
final int classCount = header.getClassCount();
final long[][] methodFlags = segment.getClassBands().getMethodFlags();
final int[] codeMaxNALocals = segment.getClassBands().getCodeMaxNALocals();
final int[] codeMaxStack = segment.getClassBands().getCodeMaxStack();
final ArrayList<Attribute>[][] methodAttributes = segment.getClassBands().getMethodAttributes();
final String[][] methodDescr = segment.getClassBands().getMethodDescr();
final AttributeLayoutMap attributeDefinitionMap = segment.getAttrDefinitionBands().getAttributeDefinitionMap();
final AttributeLayout abstractModifier = attributeDefinitionMap.getAttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_METHOD);
final AttributeLayout nativeModifier = attributeDefinitionMap.getAttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_METHOD);
final AttributeLayout staticModifier = attributeDefinitionMap.getAttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_METHOD);
final int[] wideByteCodeArray = new int[wideByteCodes.size()];
for (int index = 0; index < wideByteCodeArray.length; index++) {
wideByteCodeArray[index] = wideByteCodes.get(index).intValue();
}
final OperandManager operandManager = new OperandManager(bcCaseCount, bcCaseValue, bcByte, bcShort, bcLocal, bcLabel, bcIntRef, bcFloatRef, bcLongRef,
bcDoubleRef, bcStringRef, bcClassRef, bcFieldRef, bcMethodRef, bcIMethodRef, bcThisField, bcSuperField, bcThisMethod, bcSuperMethod, bcInitRef,
wideByteCodeArray);
operandManager.setSegment(segment);
int i = 0;
final ArrayList<List<Attribute>> orderedCodeAttributes = segment.getClassBands().getOrderedCodeAttributes();
int codeAttributeIndex = 0;
// Exception table fields
final int[] handlerCount = segment.getClassBands().getCodeHandlerCount();
final int[][] handlerStartPCs = segment.getClassBands().getCodeHandlerStartP();
final int[][] handlerEndPCs = segment.getClassBands().getCodeHandlerEndPO();
final int[][] handlerCatchPCs = segment.getClassBands().getCodeHandlerCatchPO();
final int[][] handlerClassTypes = segment.getClassBands().getCodeHandlerClassRCN();
final boolean allCodeHasFlags = segment.getSegmentHeader().getOptions().hasAllCodeFlags();
final boolean[] codeHasFlags = segment.getClassBands().getCodeHasAttributes();
for (int c = 0; c < classCount; c++) {
final int numberOfMethods = methodFlags[c].length;
for (int m = 0; m < numberOfMethods; m++) {
final long methodFlag = methodFlags[c][m];
if (!abstractModifier.matches(methodFlag) && !nativeModifier.matches(methodFlag)) {
final int maxStack = codeMaxStack[i];
int maxLocal = codeMaxNALocals[i];
if (!staticModifier.matches(methodFlag)) {
maxLocal++; // one for 'this' parameter
}
// I believe this has to take wide arguments into account
maxLocal += SegmentUtils.countInvokeInterfaceArgs(methodDescr[c][m]);
final String[] cpClass = segment.getCpBands().getCpClass();
operandManager.setCurrentClass(cpClass[segment.getClassBands().getClassThisInts()[c]]);
operandManager.setSuperClass(cpClass[segment.getClassBands().getClassSuperInts()[c]]);
final List<ExceptionTableEntry> exceptionTable = new ArrayList<>();
if (handlerCount != null) {
for (int j = 0; j < handlerCount[i]; j++) {
final int handlerClass = handlerClassTypes[i][j] - 1;
CPClass cpHandlerClass = null;
if (handlerClass != -1) {
// The handlerClass will be null if the
// catch is a finally (that is, the
// exception table catch_type should be 0
cpHandlerClass = segment.getCpBands().cpClassValue(handlerClass);
}
final ExceptionTableEntry entry = new ExceptionTableEntry(handlerStartPCs[i][j], handlerEndPCs[i][j], handlerCatchPCs[i][j],
cpHandlerClass);
exceptionTable.add(entry);
}
}
final CodeAttribute codeAttr = new CodeAttribute(maxStack, maxLocal, methodByteCodePacked[c][m], segment, operandManager, exceptionTable);
final List<Attribute> methodAttributesList = methodAttributes[c][m];
// Make sure we add the code attribute in the right place
int indexForCodeAttr = 0;
for (final Attribute attribute : methodAttributesList) {
if (!(attribute instanceof NewAttribute) || ((NewAttribute) attribute).getLayoutIndex() >= 15) {
break;
}
indexForCodeAttr++;
}
methodAttributesList.add(indexForCodeAttr, codeAttr);
codeAttr.renumber(codeAttr.byteCodeOffsets);
final List<Attribute> currentAttributes;
if (allCodeHasFlags) {
currentAttributes = orderedCodeAttributes.get(i);
} else if (codeHasFlags[i]) {
currentAttributes = orderedCodeAttributes.get(codeAttributeIndex);
codeAttributeIndex++;
} else {
currentAttributes = Collections.EMPTY_LIST;
}
for (final Attribute currentAttribute : currentAttributes) {
codeAttr.addAttribute(currentAttribute);
// Fix up the line numbers if needed
if (currentAttribute.hasBCIRenumbering()) {
((BCIRenumberedAttribute) currentAttribute).renumber(codeAttr.byteCodeOffsets);
}
}
i++;
}
}
}
}