in src/main/java/com/amazon/corretto/hotpatch/org/objectweb/asm/MethodWriter.java [731:858]
public void visitFrame(
final int type,
final int numLocal,
final Object[] local,
final int numStack,
final Object[] stack) {
if (compute == COMPUTE_ALL_FRAMES) {
return;
}
if (compute == COMPUTE_INSERTED_FRAMES) {
if (currentBasicBlock.frame == null) {
// This should happen only once, for the implicit first frame (which is explicitly visited
// in ClassReader if the EXPAND_ASM_INSNS option is used - and COMPUTE_INSERTED_FRAMES
// can't be set if EXPAND_ASM_INSNS is not used).
currentBasicBlock.frame = new CurrentFrame(currentBasicBlock);
currentBasicBlock.frame.setInputFrameFromDescriptor(
symbolTable, accessFlags, descriptor, numLocal);
currentBasicBlock.frame.accept(this);
} else {
if (type == Opcodes.F_NEW) {
currentBasicBlock.frame.setInputFrameFromApiFormat(
symbolTable, numLocal, local, numStack, stack);
}
// If type is not F_NEW then it is F_INSERT by hypothesis, and currentBlock.frame contains
// the stack map frame at the current instruction, computed from the last F_NEW frame and
// the bytecode instructions in between (via calls to CurrentFrame#execute).
currentBasicBlock.frame.accept(this);
}
} else if (type == Opcodes.F_NEW) {
if (previousFrame == null) {
int argumentsSize = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
Frame implicitFirstFrame = new Frame(new Label());
implicitFirstFrame.setInputFrameFromDescriptor(
symbolTable, accessFlags, descriptor, argumentsSize);
implicitFirstFrame.accept(this);
}
currentLocals = numLocal;
int frameIndex = visitFrameStart(code.length, numLocal, numStack);
for (int i = 0; i < numLocal; ++i) {
currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, local[i]);
}
for (int i = 0; i < numStack; ++i) {
currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, stack[i]);
}
visitFrameEnd();
} else {
if (symbolTable.getMajorVersion() < Opcodes.V1_6) {
throw new IllegalArgumentException("Class versions V1_5 or less must use F_NEW frames.");
}
int offsetDelta;
if (stackMapTableEntries == null) {
stackMapTableEntries = new ByteVector();
offsetDelta = code.length;
} else {
offsetDelta = code.length - previousFrameOffset - 1;
if (offsetDelta < 0) {
if (type == Opcodes.F_SAME) {
return;
} else {
throw new IllegalStateException();
}
}
}
switch (type) {
case Opcodes.F_FULL:
currentLocals = numLocal;
stackMapTableEntries.putByte(Frame.FULL_FRAME).putShort(offsetDelta).putShort(numLocal);
for (int i = 0; i < numLocal; ++i) {
putFrameType(local[i]);
}
stackMapTableEntries.putShort(numStack);
for (int i = 0; i < numStack; ++i) {
putFrameType(stack[i]);
}
break;
case Opcodes.F_APPEND:
currentLocals += numLocal;
stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED + numLocal).putShort(offsetDelta);
for (int i = 0; i < numLocal; ++i) {
putFrameType(local[i]);
}
break;
case Opcodes.F_CHOP:
currentLocals -= numLocal;
stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED - numLocal).putShort(offsetDelta);
break;
case Opcodes.F_SAME:
if (offsetDelta < 64) {
stackMapTableEntries.putByte(offsetDelta);
} else {
stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED).putShort(offsetDelta);
}
break;
case Opcodes.F_SAME1:
if (offsetDelta < 64) {
stackMapTableEntries.putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME + offsetDelta);
} else {
stackMapTableEntries
.putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
.putShort(offsetDelta);
}
putFrameType(stack[0]);
break;
default:
throw new IllegalArgumentException();
}
previousFrameOffset = code.length;
++stackMapTableNumberOfEntries;
}
if (compute == COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES) {
relativeStackSize = numStack;
for (int i = 0; i < numStack; ++i) {
if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) {
relativeStackSize++;
}
}
if (relativeStackSize > maxRelativeStackSize) {
maxRelativeStackSize = relativeStackSize;
}
}
maxStack = Math.max(maxStack, numStack);
maxLocals = Math.max(maxLocals, currentLocals);
}