Previous CloneSet | Next CloneSet | Back to Main Report |
Clone Mass | Clones in CloneSet | Parameter Count | Clone Similarity | Syntax Category [Sequence Length] |
---|---|---|---|---|
359 | 5 | 1 | 0.996 | statement_sequence[10] |
Clone Abstraction | Parameter Bindings |
Clone Instance (Click to see clone) | Line Count | Source Line | Source File |
---|---|---|---|
1 | 359 | 2432 | plugins/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java |
2 | 361 | 2891 | plugins/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java |
3 | 359 | 3323 | plugins/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java |
4 | 358 | 3986 | plugins/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java |
5 | 360 | 4609 | plugins/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java |
| ||||
if ((this.produceAttributes& ClassFileConstants.ATTR_STACK_MAP) != 0) { final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; final int framesPositionsSize = framesPositions.size(); int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count if (numberOfFrames > 0) { ArrayList framePositions = new ArrayList(framesPositionsSize); framePositions.addAll(framesPositions); Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); } int stackMapTableAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); this.contents[localContentsOffset++ ] = (byte) (stackMapTableAttributeNameIndex >> 8); this.contents[localContentsOffset++ ] = (byte) stackMapTableAttributeNameIndex; int stackMapTableAttributeLengthOffset = localContentsOffset; // generate the attribute localContentsOffset += 4; numberOfFrames = 0; int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; StackMapFrame currentFrame = (StackMapFrame) frames.get(0); StackMapFrame prevFrame = null; int framesSize = frames.size(); int frameIndex = 0; for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { // select next frame prevFrame = currentFrame; currentFrame = null; for (; frameIndex < framesSize; frameIndex++) { currentFrame = (StackMapFrame) frames.get(frameIndex); if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { break; } } if (currentFrame == null) break; numberOfFrames++; int offsetDelta = currentFrame.getOffsetDelta(prevFrame); switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); int numberOfLocals = currentFrame.getNumberOfLocals(); for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfDifferentLocals--; } } break; case StackMapFrame.SAME_FRAME: if (localContentsOffset + 1 >= this.contents.length) { resizeContents(1); } this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_FRAME_EXTENDED: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } this.contents[localContentsOffset++ ] = (byte) 251; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.CHOP_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS: if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[localContentsOffset++ ] = (byte) (offsetDelta + 64); if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED: if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } this.contents[localContentsOffset++ ] = (byte) 247; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; default: // FULL_FRAME if (localContentsOffset + 5 >= this.contents.length) { resizeContents(5); } this.contents[localContentsOffset++ ] = (byte) 255; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int numberOfLocalOffset = localContentsOffset; localContentsOffset += 2; // leave two spots for number of locals int numberOfLocalEntries = 0; numberOfLocals = currentFrame.getNumberOfLocals(); int numberOfEntries = 0; int localsLength = currentFrame.locals == null ? 0: currentFrame.locals.length; for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfLocalEntries++; } numberOfEntries++; } if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[numberOfLocalOffset++ ] = (byte) (numberOfEntries >> 8); this.contents[numberOfLocalOffset] = (byte) numberOfEntries; int numberOfStackItems = currentFrame.numberOfStackItems; this.contents[localContentsOffset++ ] = (byte) (numberOfStackItems >> 8); this.contents[localContentsOffset++ ] = (byte) numberOfStackItems; for (int i = 0; i < numberOfStackItems; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.stackItems[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } } } } this.contents[numberOfFramesOffset++ ] = (byte) (numberOfFrames >> 8); this.contents[numberOfFramesOffset] = (byte) numberOfFrames; int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 24); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 16); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 8); this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; attributeNumber++; } } // update the number of attributes // ensure first that there is enough space available inside the contents array if (codeAttributeAttributeOffset + 2 >= this.contents.length) { resizeContents(2); } this.contents[codeAttributeAttributeOffset++ ] = (byte) (attributeNumber >> 8); this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; // update the attribute length int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; contentsOffset = localContentsOffset; |
| ||||
if ((this.produceAttributes& ClassFileConstants.ATTR_STACK_MAP) != 0) { final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; final int framesPositionsSize = framesPositions.size(); int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count if (numberOfFrames > 0) { ArrayList framePositions = new ArrayList(framesPositionsSize); framePositions.addAll(framesPositions); Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); } int stackMapTableAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); this.contents[localContentsOffset++ ] = (byte) (stackMapTableAttributeNameIndex >> 8); this.contents[localContentsOffset++ ] = (byte) stackMapTableAttributeNameIndex; int stackMapTableAttributeLengthOffset = localContentsOffset; // generate the attribute localContentsOffset += 4; numberOfFrames = 0; int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; StackMapFrame currentFrame = (StackMapFrame) frames.get(0); StackMapFrame prevFrame = null; int framesSize = frames.size(); int frameIndex = 0; for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { // select next frame prevFrame = currentFrame; currentFrame = null; for (; frameIndex < framesSize; frameIndex++) { currentFrame = (StackMapFrame) frames.get(frameIndex); if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { break; } } if (currentFrame == null) break; // generate current frame // need to find differences between the current frame and the previous frame numberOfFrames++; int offsetDelta = currentFrame.getOffsetDelta(prevFrame); switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); int numberOfLocals = currentFrame.getNumberOfLocals(); for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfDifferentLocals--; } } break; case StackMapFrame.SAME_FRAME: if (localContentsOffset + 1 >= this.contents.length) { resizeContents(1); } this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_FRAME_EXTENDED: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } this.contents[localContentsOffset++ ] = (byte) 251; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.CHOP_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS: if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[localContentsOffset++ ] = (byte) (offsetDelta + 64); if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED: if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } this.contents[localContentsOffset++ ] = (byte) 247; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; default: // FULL_FRAME if (localContentsOffset + 5 >= this.contents.length) { resizeContents(5); } this.contents[localContentsOffset++ ] = (byte) 255; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int numberOfLocalOffset = localContentsOffset; localContentsOffset += 2; // leave two spots for number of locals int numberOfLocalEntries = 0; numberOfLocals = currentFrame.getNumberOfLocals(); int numberOfEntries = 0; int localsLength = currentFrame.locals == null ? 0: currentFrame.locals.length; for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfLocalEntries++; } numberOfEntries++; } if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[numberOfLocalOffset++ ] = (byte) (numberOfEntries >> 8); this.contents[numberOfLocalOffset] = (byte) numberOfEntries; int numberOfStackItems = currentFrame.numberOfStackItems; this.contents[localContentsOffset++ ] = (byte) (numberOfStackItems >> 8); this.contents[localContentsOffset++ ] = (byte) numberOfStackItems; for (int i = 0; i < numberOfStackItems; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.stackItems[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } } } } this.contents[numberOfFramesOffset++ ] = (byte) (numberOfFrames >> 8); this.contents[numberOfFramesOffset] = (byte) numberOfFrames; int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 24); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 16); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 8); this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; attributeNumber++; } } // update the number of attributes // ensure first that there is enough space available inside the contents array if (codeAttributeAttributeOffset + 2 >= this.contents.length) { resizeContents(2); } this.contents[codeAttributeAttributeOffset++ ] = (byte) (attributeNumber >> 8); this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; // update the attribute length int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; contentsOffset = localContentsOffset; |
| ||||
if ((this.produceAttributes& ClassFileConstants.ATTR_STACK_MAP) != 0) { final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; final int framesPositionsSize = framesPositions.size(); int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count if (numberOfFrames > 0) { ArrayList framePositions = new ArrayList(framesPositionsSize); framePositions.addAll(framesPositions); Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); } int stackMapTableAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); this.contents[localContentsOffset++ ] = (byte) (stackMapTableAttributeNameIndex >> 8); this.contents[localContentsOffset++ ] = (byte) stackMapTableAttributeNameIndex; int stackMapTableAttributeLengthOffset = localContentsOffset; // generate the attribute localContentsOffset += 4; numberOfFrames = 0; int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; StackMapFrame currentFrame = (StackMapFrame) frames.get(0); StackMapFrame prevFrame = null; int framesSize = frames.size(); int frameIndex = 0; for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { // select next frame prevFrame = currentFrame; currentFrame = null; for (; frameIndex < framesSize; frameIndex++) { currentFrame = (StackMapFrame) frames.get(frameIndex); if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { break; } } if (currentFrame == null) break; numberOfFrames++; int offsetDelta = currentFrame.getOffsetDelta(prevFrame); switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); int numberOfLocals = currentFrame.getNumberOfLocals(); for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfDifferentLocals--; } } break; case StackMapFrame.SAME_FRAME: if (localContentsOffset + 1 >= this.contents.length) { resizeContents(1); } this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_FRAME_EXTENDED: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } this.contents[localContentsOffset++ ] = (byte) 251; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.CHOP_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS: if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[localContentsOffset++ ] = (byte) (offsetDelta + 64); if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED: if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } this.contents[localContentsOffset++ ] = (byte) 247; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; default: // FULL_FRAME if (localContentsOffset + 5 >= this.contents.length) { resizeContents(5); } this.contents[localContentsOffset++ ] = (byte) 255; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int numberOfLocalOffset = localContentsOffset; localContentsOffset += 2; // leave two spots for number of locals int numberOfLocalEntries = 0; numberOfLocals = currentFrame.getNumberOfLocals(); int numberOfEntries = 0; int localsLength = currentFrame.locals == null ? 0: currentFrame.locals.length; for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfLocalEntries++; } numberOfEntries++; } if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[numberOfLocalOffset++ ] = (byte) (numberOfEntries >> 8); this.contents[numberOfLocalOffset] = (byte) numberOfEntries; int numberOfStackItems = currentFrame.numberOfStackItems; this.contents[localContentsOffset++ ] = (byte) (numberOfStackItems >> 8); this.contents[localContentsOffset++ ] = (byte) numberOfStackItems; for (int i = 0; i < numberOfStackItems; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.stackItems[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } } } } this.contents[numberOfFramesOffset++ ] = (byte) (numberOfFrames >> 8); this.contents[numberOfFramesOffset] = (byte) numberOfFrames; int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 24); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 16); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 8); this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; attributeNumber++; } } // then we do the local variable attribute // update the number of attributes// ensure first that there is enough space available inside the localContents array if (codeAttributeAttributeOffset + 2 >= this.contents.length) { resizeContents(2); } this.contents[codeAttributeAttributeOffset++ ] = (byte) (attributeNumber >> 8); this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; // update the attribute length int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; contentsOffset = localContentsOffset; |
| ||||
if ((this.produceAttributes& ClassFileConstants.ATTR_STACK_MAP) != 0) { final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; final int framesPositionsSize = framesPositions.size(); int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count if (numberOfFrames > 0) { ArrayList framePositions = new ArrayList(framesPositionsSize); framePositions.addAll(framesPositions); Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); } int stackMapTableAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); this.contents[localContentsOffset++ ] = (byte) (stackMapTableAttributeNameIndex >> 8); this.contents[localContentsOffset++ ] = (byte) stackMapTableAttributeNameIndex; int stackMapTableAttributeLengthOffset = localContentsOffset; // generate the attribute localContentsOffset += 4; numberOfFrames = 0; int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; StackMapFrame currentFrame = (StackMapFrame) frames.get(0); StackMapFrame prevFrame = null; int framesSize = frames.size(); int frameIndex = 0; for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { // select next frame prevFrame = currentFrame; currentFrame = null; for (; frameIndex < framesSize; frameIndex++) { currentFrame = (StackMapFrame) frames.get(frameIndex); if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { break; } } if (currentFrame == null) break; numberOfFrames++; int offsetDelta = currentFrame.getOffsetDelta(prevFrame); switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); int numberOfLocals = currentFrame.getNumberOfLocals(); for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfDifferentLocals--; } } break; case StackMapFrame.SAME_FRAME: if (localContentsOffset + 1 >= this.contents.length) { resizeContents(1); } this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_FRAME_EXTENDED: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } this.contents[localContentsOffset++ ] = (byte) 251; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.CHOP_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS: if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[localContentsOffset++ ] = (byte) (offsetDelta + 64); if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED: if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } this.contents[localContentsOffset++ ] = (byte) 247; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; default: // FULL_FRAME if (localContentsOffset + 5 >= this.contents.length) { resizeContents(5); } this.contents[localContentsOffset++ ] = (byte) 255; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int numberOfLocalOffset = localContentsOffset; localContentsOffset += 2; // leave two spots for number of locals int numberOfLocalEntries = 0; numberOfLocals = currentFrame.getNumberOfLocals(); int numberOfEntries = 0; int localsLength = currentFrame.locals == null ? 0: currentFrame.locals.length; for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfLocalEntries++; } numberOfEntries++; } if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[numberOfLocalOffset++ ] = (byte) (numberOfEntries >> 8); this.contents[numberOfLocalOffset] = (byte) numberOfEntries; int numberOfStackItems = currentFrame.numberOfStackItems; this.contents[localContentsOffset++ ] = (byte) (numberOfStackItems >> 8); this.contents[localContentsOffset++ ] = (byte) numberOfStackItems; for (int i = 0; i < numberOfStackItems; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.stackItems[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } } } } this.contents[numberOfFramesOffset++ ] = (byte) (numberOfFrames >> 8); this.contents[numberOfFramesOffset] = (byte) numberOfFrames; int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 24); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 16); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 8); this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; attributeNumber++; } } // update the number of attributes// ensure first that there is enough space available inside the localContents array if (codeAttributeAttributeOffset + 2 >= this.contents.length) { resizeContents(2); } this.contents[codeAttributeAttributeOffset++ ] = (byte) (attributeNumber >> 8); this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber; // update the attribute length int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; contentsOffset = localContentsOffset; |
| ||||
if ((this.produceAttributes& ClassFileConstants.ATTR_STACK_MAP) != 0) { final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; final int framesPositionsSize = framesPositions.size(); int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count if (numberOfFrames > 0) { ArrayList framePositions = new ArrayList(framesPositionsSize); framePositions.addAll(framesPositions); Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); } int stackMapTableAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); this.contents[localContentsOffset++ ] = (byte) (stackMapTableAttributeNameIndex >> 8); this.contents[localContentsOffset++ ] = (byte) stackMapTableAttributeNameIndex; int stackMapTableAttributeLengthOffset = localContentsOffset; // generate the attribute localContentsOffset += 4; numberOfFrames = 0; int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; StackMapFrame currentFrame = (StackMapFrame) frames.get(0); StackMapFrame prevFrame = null; int framesSize = frames.size(); int frameIndex = 0; for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { // select next frame prevFrame = currentFrame; currentFrame = null; for (; frameIndex < framesSize; frameIndex++) { currentFrame = (StackMapFrame) frames.get(frameIndex); if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { break; } } if (currentFrame == null) break; numberOfFrames++; int offsetDelta = currentFrame.getOffsetDelta(prevFrame); switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); int numberOfLocals = currentFrame.getNumberOfLocals(); for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfDifferentLocals--; } } break; case StackMapFrame.SAME_FRAME: if (localContentsOffset + 1 >= this.contents.length) { resizeContents(1); } this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_FRAME_EXTENDED: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } this.contents[localContentsOffset++ ] = (byte) 251; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.CHOP_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS: if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[localContentsOffset++ ] = (byte) (offsetDelta + 64); if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED: if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } this.contents[localContentsOffset++ ] = (byte) 247; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; default: // FULL_FRAME if (localContentsOffset + 5 >= this.contents.length) { resizeContents(5); } this.contents[localContentsOffset++ ] = (byte) 255; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int numberOfLocalOffset = localContentsOffset; localContentsOffset += 2; // leave two spots for number of locals int numberOfLocalEntries = 0; numberOfLocals = currentFrame.getNumberOfLocals(); int numberOfEntries = 0; int localsLength = currentFrame.locals == null ? 0: currentFrame.locals.length; for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfLocalEntries++; } numberOfEntries++; } if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[numberOfLocalOffset++ ] = (byte) (numberOfEntries >> 8); this.contents[numberOfLocalOffset] = (byte) numberOfEntries; int numberOfStackItems = currentFrame.numberOfStackItems; this.contents[localContentsOffset++ ] = (byte) (numberOfStackItems >> 8); this.contents[localContentsOffset++ ] = (byte) numberOfStackItems; for (int i = 0; i < numberOfStackItems; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.stackItems[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } } } } this.contents[numberOfFramesOffset++ ] = (byte) (numberOfFrames >> 8); this.contents[numberOfFramesOffset] = (byte) numberOfFrames; int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 24); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 16); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 8); this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; attributeNumber++; } } // update the number of attributes // ensure first that there is enough space available inside the contents array if (codeAttributeAttributeOffset + 2 >= this.contents.length) { resizeContents(2); } contents[codeAttributeAttributeOffset++ ] = (byte) (attributeNumber >> 8); contents[codeAttributeAttributeOffset] = (byte) attributeNumber; // update the attribute length int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); contents[codeAttributeOffset + 5] = (byte) codeAttributeLength; contentsOffset = localContentsOffset; |
| |||
if ((this.produceAttributes&ClassFileConstants.ATTR_STACK_MAP) != 0) { final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; final int framesPositionsSize = framesPositions.size(); int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count if (numberOfFrames > 0) { ArrayList framePositions = new ArrayList(framesPositionsSize); framePositions.addAll(framesPositions); Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); } int stackMapTableAttributeNameIndex = constantPool.literalIndex(AttributeNamesConstants.StackMapTableName); this.contents[localContentsOffset++ ] = (byte) (stackMapTableAttributeNameIndex >> 8); this.contents[localContentsOffset++ ] = (byte) stackMapTableAttributeNameIndex; int stackMapTableAttributeLengthOffset = localContentsOffset; // generate the attribute localContentsOffset += 4; numberOfFrames = 0; int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; StackMapFrame currentFrame = (StackMapFrame) frames.get(0); StackMapFrame prevFrame = null; int framesSize = frames.size(); int frameIndex = 0; for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { // select next frame prevFrame = currentFrame; currentFrame = null; for (; frameIndex < framesSize; frameIndex++) { currentFrame = (StackMapFrame) frames.get(frameIndex); if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { break; } } if (currentFrame == null) break; // generate current frame // need to find differences between the current frame and the previous frame numberOfFrames++; int offsetDelta = currentFrame.getOffsetDelta(prevFrame); switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals); int numberOfLocals = currentFrame.getNumberOfLocals(); for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) { if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfDifferentLocals--; } } break; case StackMapFrame.SAME_FRAME: if (localContentsOffset + 1 >= this.contents.length) { resizeContents(1); } this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_FRAME_EXTENDED: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } this.contents[localContentsOffset++ ] = (byte) 251; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.CHOP_FRAME: if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++ ] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS: if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[localContentsOffset++ ] = (byte) (offsetDelta + 64); if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED: if (localContentsOffset + 6 >= this.contents.length) { resizeContents(6); } this.contents[localContentsOffset++ ] = (byte) 247; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; if (currentFrame.stackItems[0] == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (currentFrame.stackItems[0].id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: VerificationTypeInfo info = currentFrame.stackItems[0]; this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } break; default: // FULL_FRAME if (localContentsOffset + 5 >= this.contents.length) { resizeContents(5); } this.contents[localContentsOffset++ ] = (byte) 255; this.contents[localContentsOffset++ ] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++ ] = (byte) offsetDelta; int numberOfLocalOffset = localContentsOffset; localContentsOffset += 2; // leave two spots for number of locals int numberOfLocalEntries = 0; numberOfLocals = currentFrame.getNumberOfLocals(); int numberOfEntries = 0; int localsLength = currentFrame.locals == null ? 0: currentFrame.locals.length; for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.locals[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; i++; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; i++; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } numberOfLocalEntries++; } numberOfEntries++; } if (localContentsOffset + 4 >= this.contents.length) { resizeContents(4); } this.contents[numberOfLocalOffset++ ] = (byte) (numberOfEntries >> 8); this.contents[numberOfLocalOffset] = (byte) numberOfEntries; int numberOfStackItems = currentFrame.numberOfStackItems; this.contents[localContentsOffset++ ] = (byte) (numberOfStackItems >> 8); this.contents[localContentsOffset++ ] = (byte) numberOfStackItems; for (int i = 0; i < numberOfStackItems; i++) { if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } VerificationTypeInfo info = currentFrame.stackItems[i]; if (info == null) { this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_TOP; } else { switch (info.id()) { case T_boolean: case T_byte: case T_char: case T_int: case T_short: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_INTEGER; break; case T_float: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_FLOAT; break; case T_long: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_LONG; break; case T_double: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_DOUBLE; break; case T_null: this.contents[localContentsOffset++ ] = (byte) VerificationTypeInfo.ITEM_NULL; break; default: this.contents[localContentsOffset++ ] = (byte) info.tag; switch (info.tag) { case VerificationTypeInfo.ITEM_UNINITIALIZED: int offset = info.offset; this.contents[localContentsOffset++ ] = (byte) (offset >> 8); this.contents[localContentsOffset++ ] = (byte) offset; break; case VerificationTypeInfo.ITEM_OBJECT: int indexForType = constantPool.literalIndexForType(info.constantPoolName()); this.contents[localContentsOffset++ ] = (byte) (indexForType >> 8); this.contents[localContentsOffset++ ] = (byte) indexForType; } } } } } } this.contents[numberOfFramesOffset++ ] = (byte) (numberOfFrames >> 8); this.contents[numberOfFramesOffset] = (byte) numberOfFrames; int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4; this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 24); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 16); this.contents[stackMapTableAttributeLengthOffset++ ] = (byte) (attributeLength >> 8); this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength; attributeNumber++; } } // update the number of attributes // ensure first that there is enough space available inside the contents array // then we do the local variable attribute // update the number of attributes// ensure first that there is enough space available inside the localContents array if (codeAttributeAttributeOffset + 2 >= this.contents.length) { resizeContents(2); } [[#variableb2e40f00]][codeAttributeAttributeOffset++ ] = (byte) (attributeNumber >> 8); [[#variableb2e40f00]][codeAttributeAttributeOffset] = (byte) attributeNumber; // update the attribute length int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6); [[#variableb2e40f00]][codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24); [[#variableb2e40f00]][codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16); [[#variableb2e40f00]][codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8); [[#variableb2e40f00]][codeAttributeOffset + 5] = (byte) codeAttributeLength; contentsOffset = localContentsOffset; |
CloneAbstraction |
Parameter Index | Clone Instance | Parameter Name | Value |
---|---|---|---|
1 | 1 | [[#b2e40f00]] | this.contents |
1 | 2 | [[#b2e40f00]] | contents |
1 | 3 | [[#b2e40f00]] | this.contents |
1 | 4 | [[#b2e40f00]] | this.contents |
1 | 5 | [[#b2e40f00]] | this.contents |