in asm/src/main/java/org/objectweb/asm/MethodWriter.java [909:968]
public void visitVarInsn(final int opcode, final int varIndex) {
lastBytecodeOffset = code.length;
// Add the instruction to the bytecode of the method.
if (varIndex < 4 && opcode != Opcodes.RET) {
int optimizedOpcode;
if (opcode < Opcodes.ISTORE) {
optimizedOpcode = Constants.ILOAD_0 + ((opcode - Opcodes.ILOAD) << 2) + varIndex;
} else {
optimizedOpcode = Constants.ISTORE_0 + ((opcode - Opcodes.ISTORE) << 2) + varIndex;
}
code.putByte(optimizedOpcode);
} else if (varIndex >= 256) {
code.putByte(Constants.WIDE).put12(opcode, varIndex);
} else {
code.put11(opcode, varIndex);
}
// If needed, update the maximum stack size and number of locals, and stack map frames.
if (currentBasicBlock != null) {
if (compute == COMPUTE_ALL_FRAMES || compute == COMPUTE_INSERTED_FRAMES) {
currentBasicBlock.frame.execute(opcode, varIndex, null, null);
} else {
if (opcode == Opcodes.RET) {
// No stack size delta.
currentBasicBlock.flags |= Label.FLAG_SUBROUTINE_END;
currentBasicBlock.outputStackSize = (short) relativeStackSize;
endCurrentBasicBlockWithNoSuccessor();
} else { // xLOAD or xSTORE
int size = relativeStackSize + STACK_SIZE_DELTA[opcode];
if (size > maxRelativeStackSize) {
maxRelativeStackSize = size;
}
relativeStackSize = size;
}
}
}
if (compute != COMPUTE_NOTHING) {
int currentMaxLocals;
if (opcode == Opcodes.LLOAD
|| opcode == Opcodes.DLOAD
|| opcode == Opcodes.LSTORE
|| opcode == Opcodes.DSTORE) {
currentMaxLocals = varIndex + 2;
} else {
currentMaxLocals = varIndex + 1;
}
if (currentMaxLocals > maxLocals) {
maxLocals = currentMaxLocals;
}
}
if (opcode >= Opcodes.ISTORE && compute == COMPUTE_ALL_FRAMES && firstHandler != null) {
// If there are exception handler blocks, each instruction within a handler range is, in
// theory, a basic block (since execution can jump from this instruction to the exception
// handler). As a consequence, the local variable types at the beginning of the handler
// block should be the merge of the local variable types at all the instructions within the
// handler range. However, instead of creating a basic block for each instruction, we can
// get the same result in a more efficient way. Namely, by starting a new basic block after
// each xSTORE instruction, which is what we do here.
visitLabel(new Label());
}
}