private void writeDebugAndCodeItems(@Nonnull DexDataWriter offsetWriter,
@Nonnull DeferredOutputStream temp) throws IOException {
ByteArrayOutputStream ehBuf = new ByteArrayOutputStream();
debugSectionOffset = offsetWriter.getPosition();
DebugWriter debugWriter =
new DebugWriter(stringSection, typeSection, offsetWriter);
DexDataWriter codeWriter = new DexDataWriter(temp, 0);
List> codeOffsets = Lists.newArrayList();
for (ClassKey classKey: classSection.getSortedClasses()) {
Collection extends MethodKey> directMethods = classSection.getSortedDirectMethods(classKey);
Collection extends MethodKey> virtualMethods = classSection.getSortedVirtualMethods(classKey);
Iterable methods = Iterables.concat(directMethods, virtualMethods);
for (MethodKey methodKey: methods) {
List extends TryBlock extends ExceptionHandler>> tryBlocks =
classSection.getTryBlocks(methodKey);
Iterable extends Instruction> instructions = classSection.getInstructions(methodKey);
Iterable extends DebugItem> debugItems = classSection.getDebugItems(methodKey);
if (instructions != null && stringSection.hasJumboIndexes()) {
boolean needsFix = false;
for (Instruction instruction: instructions) {
if (instruction.getOpcode() == Opcode.CONST_STRING) {
if (stringSection.getItemIndex(
(StringRef)((ReferenceInstruction)instruction).getReference()) >= 65536) {
needsFix = true;
break;
}
}
}
if (needsFix) {
MutableMethodImplementation mutableMethodImplementation =
classSection.makeMutableMethodImplementation(methodKey);
fixInstructions(mutableMethodImplementation);
instructions = mutableMethodImplementation.getInstructions();
tryBlocks = mutableMethodImplementation.getTryBlocks();
debugItems = mutableMethodImplementation.getDebugItems();
}
}
int debugItemOffset = writeDebugItem(offsetWriter, debugWriter,
classSection.getParameterNames(methodKey), debugItems);
int codeItemOffset = writeCodeItem(codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);
if (codeItemOffset != -1) {
codeOffsets.add(new CodeItemOffset(methodKey, codeItemOffset));
}
}
}
offsetWriter.align();
codeSectionOffset = offsetWriter.getPosition();
codeWriter.close();
temp.writeTo(offsetWriter);
temp.close();
for (CodeItemOffset codeOffset: codeOffsets) {
classSection.setCodeItemOffset(codeOffset.method, codeSectionOffset + codeOffset.codeOffset);
}
}