(
final int type,
final int nLocal,
final Object[] local,
final int nStack,
final Object[] stack)
| 737 | } |
| 738 | |
| 739 | @Override |
| 740 | public void visitFrame( |
| 741 | final int type, |
| 742 | final int nLocal, |
| 743 | final Object[] local, |
| 744 | final int nStack, |
| 745 | final Object[] stack) { |
| 746 | if (compute == COMPUTE_ALL_FRAMES) { |
| 747 | return; |
| 748 | } |
| 749 | |
| 750 | if (compute == COMPUTE_INSERTED_FRAMES) { |
| 751 | if (currentBasicBlock.frame == null) { |
| 752 | // This should happen only once, for the implicit first frame (which is explicitly visited |
| 753 | // in ClassReader if the EXPAND_ASM_INSNS option is used - and COMPUTE_INSERTED_FRAMES |
| 754 | // can't be set if EXPAND_ASM_INSNS is not used). |
| 755 | currentBasicBlock.frame = new CurrentFrame(currentBasicBlock); |
| 756 | currentBasicBlock.frame.setInputFrameFromDescriptor( |
| 757 | symbolTable, accessFlags, descriptor, nLocal); |
| 758 | currentBasicBlock.frame.accept(this); |
| 759 | } else { |
| 760 | if (type == Opcodes.F_NEW) { |
| 761 | currentBasicBlock.frame.setInputFrameFromApiFormat( |
| 762 | symbolTable, nLocal, local, nStack, stack); |
| 763 | } else { |
| 764 | // In this case type is equal to F_INSERT by hypothesis, and currentBlock.frame contains |
| 765 | // the stack map frame at the current instruction, computed from the last F_NEW frame |
| 766 | // and the bytecode instructions in between (via calls to CurrentFrame#execute). |
| 767 | } |
| 768 | currentBasicBlock.frame.accept(this); |
| 769 | } |
| 770 | } else if (type == Opcodes.F_NEW) { |
| 771 | if (previousFrame == null) { |
| 772 | int argumentsSize = Type.getArgumentsAndReturnSizes(descriptor) >> 2; |
| 773 | Frame implicitFirstFrame = new Frame(new Label()); |
| 774 | implicitFirstFrame.setInputFrameFromDescriptor( |
| 775 | symbolTable, accessFlags, descriptor, argumentsSize); |
| 776 | implicitFirstFrame.accept(this); |
| 777 | } |
| 778 | currentLocals = nLocal; |
| 779 | int frameIndex = visitFrameStart(code.length, nLocal, nStack); |
| 780 | for (int i = 0; i < nLocal; ++i) { |
| 781 | currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, local[i]); |
| 782 | } |
| 783 | for (int i = 0; i < nStack; ++i) { |
| 784 | currentFrame[frameIndex++] = Frame.getAbstractTypeFromApiFormat(symbolTable, stack[i]); |
| 785 | } |
| 786 | visitFrameEnd(); |
| 787 | } else { |
| 788 | int offsetDelta; |
| 789 | if (stackMapTableEntries == null) { |
| 790 | stackMapTableEntries = new ByteVector(); |
| 791 | offsetDelta = code.length; |
| 792 | } else { |
| 793 | offsetDelta = code.length - previousFrameOffset - 1; |
| 794 | if (offsetDelta < 0) { |
| 795 | if (type == Opcodes.F_SAME) { |
| 796 | return; |
no test coverage detected