< prev index next >

src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java

Print this page

        

*** 19,176 **** * limitations under the License. */ package com.sun.org.apache.bcel.internal.classfile; ! ! import com.sun.org.apache.bcel.internal.Constants; ! import java.io.*; /** * This class represents a stack map entry recording the types of * local variables and the the of stack items at a given byte code offset. * See CLDC specification 5.3.1.2 * ! * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> * @see StackMap * @see StackMapType */ ! public final class StackMapEntry implements Cloneable { private int byte_code_offset; - private int number_of_locals; private StackMapType[] types_of_locals; - private int number_of_stack_items; private StackMapType[] types_of_stack_items; private ConstantPool constant_pool; /** ! * Construct object from file stream. ! * @param file Input stream * @throws IOException */ ! StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException ! { ! this(file.readShort(), file.readShort(), null, -1, null, constant_pool); types_of_locals = new StackMapType[number_of_locals]; ! for(int i=0; i < number_of_locals; i++) ! types_of_locals[i] = new StackMapType(file, constant_pool); ! ! number_of_stack_items = file.readShort(); types_of_stack_items = new StackMapType[number_of_stack_items]; ! for(int i=0; i < number_of_stack_items; i++) ! types_of_stack_items[i] = new StackMapType(file, constant_pool); } ! public StackMapEntry(int byte_code_offset, int number_of_locals, ! StackMapType[] types_of_locals, ! int number_of_stack_items, ! StackMapType[] types_of_stack_items, ! ConstantPool constant_pool) { this.byte_code_offset = byte_code_offset; ! this.number_of_locals = number_of_locals; ! this.types_of_locals = types_of_locals; ! this.number_of_stack_items = number_of_stack_items; ! this.types_of_stack_items = types_of_stack_items; this.constant_pool = constant_pool; } /** * Dump stack map entry * * @param file Output file stream * @throws IOException */ ! public final void dump(DataOutputStream file) throws IOException ! { file.writeShort(byte_code_offset); ! ! file.writeShort(number_of_locals); ! for(int i=0; i < number_of_locals; i++) ! types_of_locals[i].dump(file); ! ! file.writeShort(number_of_stack_items); ! for(int i=0; i < number_of_stack_items; i++) ! types_of_stack_items[i].dump(file); } /** * @return String representation. */ public final String toString() { ! StringBuffer buf = new StringBuffer("(offset=" + byte_code_offset); ! ! if(number_of_locals > 0) { buf.append(", locals={"); ! ! for(int i=0; i < number_of_locals; i++) { buf.append(types_of_locals[i]); ! if(i < number_of_locals - 1) buf.append(", "); } ! buf.append("}"); } ! ! if(number_of_stack_items > 0) { buf.append(", stack items={"); ! ! for(int i=0; i < number_of_stack_items; i++) { buf.append(types_of_stack_items[i]); ! if(i < number_of_stack_items - 1) buf.append(", "); } ! buf.append("}"); } - buf.append(")"); - return buf.toString(); } ! public void setByteCodeOffset(int b) { byte_code_offset = b; } ! public int getByteCodeOffset() { return byte_code_offset; } ! public void setNumberOfLocals(int n) { number_of_locals = n; } ! public int getNumberOfLocals() { return number_of_locals; } ! public void setTypesOfLocals(StackMapType[] t) { types_of_locals = t; } ! public StackMapType[] getTypesOfLocals() { return types_of_locals; } ! public void setNumberOfStackItems(int n) { number_of_stack_items = n; } ! public int getNumberOfStackItems() { return number_of_stack_items; } ! public void setTypesOfStackItems(StackMapType[] t) { types_of_stack_items = t; } ! public StackMapType[] getTypesOfStackItems() { return types_of_stack_items; } /** * @return deep copy of this object */ public StackMapEntry copy() { try { ! return (StackMapEntry)clone(); ! } catch(CloneNotSupportedException e) {} ! return null; } /** * Called by objects that are traversing the nodes of the tree implicitely * defined by the contents of a Java class. I.e., the hierarchy of methods, * fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ ! public void accept(Visitor v) { v.visitStackMapEntry(this); } /** * @return Constant pool used by this object. */ ! public final ConstantPool getConstantPool() { return constant_pool; } /** * @param constant_pool Constant pool to be used for this object. */ ! public final void setConstantPool(ConstantPool constant_pool) { this.constant_pool = constant_pool; } } --- 19,440 ---- * limitations under the License. */ package com.sun.org.apache.bcel.internal.classfile; ! import java.io.DataInput; ! import java.io.DataOutputStream; ! import java.io.IOException; ! import com.sun.org.apache.bcel.internal.Const; /** * This class represents a stack map entry recording the types of * local variables and the the of stack items at a given byte code offset. * See CLDC specification 5.3.1.2 * ! * @version $Id: StackMapEntry.java 1750029 2016-06-23 22:14:38Z sebb $ * @see StackMap * @see StackMapType */ ! public final class StackMapEntry implements Node, Cloneable ! { ! ! private int frame_type; private int byte_code_offset; private StackMapType[] types_of_locals; private StackMapType[] types_of_stack_items; private ConstantPool constant_pool; + /** ! * Construct object from input stream. ! * ! * @param input Input stream * @throws IOException */ ! StackMapEntry(final DataInput input, final ConstantPool constant_pool) throws IOException { ! this(input.readByte() & 0xFF, -1, null, null, constant_pool); + if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { + byte_code_offset = frame_type - Const.SAME_FRAME; + } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && + frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + byte_code_offset = frame_type - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; + types_of_stack_items = new StackMapType[1]; + types_of_stack_items[0] = new StackMapType(input, constant_pool); + } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + byte_code_offset = input.readShort(); + types_of_stack_items = new StackMapType[1]; + types_of_stack_items[0] = new StackMapType(input, constant_pool); + } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { + byte_code_offset = input.readShort(); + } else if (frame_type == Const.SAME_FRAME_EXTENDED) { + byte_code_offset = input.readShort(); + } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { + byte_code_offset = input.readShort(); + final int number_of_locals = frame_type - 251; types_of_locals = new StackMapType[number_of_locals]; ! for (int i = 0; i < number_of_locals; i++) { ! types_of_locals[i] = new StackMapType(input, constant_pool); ! } ! } else if (frame_type == Const.FULL_FRAME) { ! byte_code_offset = input.readShort(); ! final int number_of_locals = input.readShort(); ! types_of_locals = new StackMapType[number_of_locals]; ! for (int i = 0; i < number_of_locals; i++) { ! types_of_locals[i] = new StackMapType(input, constant_pool); ! } ! final int number_of_stack_items = input.readShort(); types_of_stack_items = new StackMapType[number_of_stack_items]; ! for (int i = 0; i < number_of_stack_items; i++) { ! types_of_stack_items[i] = new StackMapType(input, constant_pool); ! } ! } else { ! /* Can't happen */ ! throw new ClassFormatException ("Invalid frame type found while parsing stack map table: " + frame_type); ! } } ! /** ! * DO NOT USE ! * ! * @param byte_code_offset ! * @param number_of_locals NOT USED ! * @param types_of_locals array of {@link StackMapType}s of locals ! * @param number_of_stack_items NOT USED ! * @param types_of_stack_items array ot {@link StackMapType}s of stack items ! * @param constant_pool the constant pool ! * @deprecated Since 6.0, use {@link #StackMapEntry(int, int, StackMapType[], StackMapType[], ConstantPool)} ! * instead ! */ ! @java.lang.Deprecated ! public StackMapEntry(final int byte_code_offset, final int number_of_locals, ! final StackMapType[] types_of_locals, final int number_of_stack_items, ! final StackMapType[] types_of_stack_items, final ConstantPool constant_pool) { this.byte_code_offset = byte_code_offset; ! this.types_of_locals = types_of_locals != null ? types_of_locals : new StackMapType[0]; ! this.types_of_stack_items = types_of_stack_items != null ? types_of_stack_items : new StackMapType[0]; this.constant_pool = constant_pool; } /** + * Create an instance + * + * @param tag the frame_type to use + * @param byte_code_offset + * @param types_of_locals array of {@link StackMapType}s of locals + * @param types_of_stack_items array ot {@link StackMapType}s of stack items + * @param constant_pool the constant pool + */ + public StackMapEntry(final int tag, final int byte_code_offset, + final StackMapType[] types_of_locals, + final StackMapType[] types_of_stack_items, final ConstantPool constant_pool) { + this.frame_type = tag; + this.byte_code_offset = byte_code_offset; + this.types_of_locals = types_of_locals != null ? types_of_locals : new StackMapType[0]; + this.types_of_stack_items = types_of_stack_items != null ? types_of_stack_items : new StackMapType[0]; + this.constant_pool = constant_pool; + } + + + /** * Dump stack map entry * * @param file Output file stream * @throws IOException */ ! public final void dump( final DataOutputStream file ) throws IOException { ! file.write(frame_type); ! if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { ! // nothing to be done ! } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && ! frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { ! types_of_stack_items[0].dump(file); ! } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { file.writeShort(byte_code_offset); ! types_of_stack_items[0].dump(file); ! } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { ! file.writeShort(byte_code_offset); ! } else if (frame_type == Const.SAME_FRAME_EXTENDED) { ! file.writeShort(byte_code_offset); ! } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { ! file.writeShort(byte_code_offset); ! for (final StackMapType type : types_of_locals) { ! type.dump(file); ! } ! } else if (frame_type == Const.FULL_FRAME) { ! file.writeShort(byte_code_offset); ! file.writeShort(types_of_locals.length); ! for (final StackMapType type : types_of_locals) { ! type.dump(file); ! } ! file.writeShort(types_of_stack_items.length); ! for (final StackMapType type : types_of_stack_items) { ! type.dump(file); ! } ! } else { ! /* Can't happen */ ! throw new ClassFormatException ("Invalid Stack map table tag: " + frame_type); ! } } + /** * @return String representation. */ + @Override public final String toString() { ! final StringBuilder buf = new StringBuilder(64); ! buf.append("("); ! if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { ! buf.append("SAME"); ! } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && ! frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { ! buf.append("SAME_LOCALS_1_STACK"); ! } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { ! buf.append("SAME_LOCALS_1_STACK_EXTENDED"); ! } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { ! buf.append("CHOP ").append(String.valueOf(251-frame_type)); ! } else if (frame_type == Const.SAME_FRAME_EXTENDED) { ! buf.append("SAME_EXTENDED"); ! } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { ! buf.append("APPEND ").append(String.valueOf(frame_type-251)); ! } else if (frame_type == Const.FULL_FRAME) { ! buf.append("FULL"); ! } else { ! buf.append("UNKNOWN (").append(frame_type).append(")"); ! } ! buf.append(", offset delta=").append(byte_code_offset); ! if (types_of_locals.length > 0) { buf.append(", locals={"); ! for (int i = 0; i < types_of_locals.length; i++) { buf.append(types_of_locals[i]); ! if (i < types_of_locals.length - 1) { buf.append(", "); } ! } buf.append("}"); } ! if (types_of_stack_items.length > 0) { buf.append(", stack items={"); ! for (int i = 0; i < types_of_stack_items.length; i++) { buf.append(types_of_stack_items[i]); ! if (i < types_of_stack_items.length - 1) { buf.append(", "); } ! } buf.append("}"); } buf.append(")"); return buf.toString(); } ! /** ! * Calculate stack map entry size ! * ! */ ! int getMapEntrySize() { ! if (frame_type >= Const.SAME_FRAME && frame_type <= Const.SAME_FRAME_MAX) { ! return 1; ! } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && ! frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { ! return 1 + (types_of_stack_items[0].hasIndex() ? 3 : 1); ! } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { ! return 3 + (types_of_stack_items[0].hasIndex() ? 3 : 1); ! } else if (frame_type >= Const.CHOP_FRAME && frame_type <= Const.CHOP_FRAME_MAX) { ! return 3; ! } else if (frame_type == Const.SAME_FRAME_EXTENDED) { ! return 3; ! } else if (frame_type >= Const.APPEND_FRAME && frame_type <= Const.APPEND_FRAME_MAX) { ! int len = 3; ! for (final StackMapType types_of_local : types_of_locals) { ! len += types_of_local.hasIndex() ? 3 : 1; ! } ! return len; ! } else if (frame_type == Const.FULL_FRAME) { ! int len = 7; ! for (final StackMapType types_of_local : types_of_locals) { ! len += types_of_local.hasIndex() ? 3 : 1; ! } ! for (final StackMapType types_of_stack_item : types_of_stack_items) { ! len += types_of_stack_item.hasIndex() ? 3 : 1; ! } ! return len; ! } else { ! throw new RuntimeException("Invalid StackMap frame_type: " + frame_type); ! } ! } ! ! ! public void setFrameType( final int f ) { ! if (f >= Const.SAME_FRAME && f <= Const.SAME_FRAME_MAX) { ! byte_code_offset = f - Const.SAME_FRAME; ! } else if (f >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && ! f <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { ! byte_code_offset = f - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; ! } else if (f == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (f >= Const.CHOP_FRAME && f <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (f == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (f >= Const.APPEND_FRAME && f <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (f == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock ! } else { ! throw new RuntimeException("Invalid StackMap frame_type"); ! } ! frame_type = f; ! } ! ! ! public int getFrameType() { ! return frame_type; ! } ! ! ! public void setByteCodeOffset( final int new_offset ) { ! if (new_offset < 0 || new_offset > 32767) { ! throw new RuntimeException("Invalid StackMap offset: " + new_offset); ! } ! ! if (frame_type >= Const.SAME_FRAME && ! frame_type <= Const.SAME_FRAME_MAX) { ! if (new_offset > Const.SAME_FRAME_MAX) { ! frame_type = Const.SAME_FRAME_EXTENDED; ! } else { ! frame_type = new_offset; ! } ! } else if (frame_type >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && ! frame_type <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { ! if (new_offset > Const.SAME_FRAME_MAX) { ! frame_type = Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; ! } else { ! frame_type = Const.SAME_LOCALS_1_STACK_ITEM_FRAME + new_offset; ! } ! } else if (frame_type == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (frame_type >= Const.CHOP_FRAME && ! frame_type <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (frame_type == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (frame_type >= Const.APPEND_FRAME && ! frame_type <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock ! } else if (frame_type == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock ! } else { ! throw new RuntimeException("Invalid StackMap frame_type: " + frame_type); ! } ! byte_code_offset = new_offset; ! } ! ! ! /** ! * Update the distance (as an offset delta) from this StackMap ! * entry to the next. Note that this might cause the the ! * frame type to change. Note also that delta may be negative. ! * ! * @param delta offset delta ! */ ! public void updateByteCodeOffset(final int delta) { ! setByteCodeOffset(byte_code_offset + delta); ! } ! ! ! public int getByteCodeOffset() { ! return byte_code_offset; ! } ! ! ! /** ! * ! * @deprecated since 6.0 ! */ ! @java.lang.Deprecated ! public void setNumberOfLocals( final int n ) { // TODO unused ! } ! ! ! public int getNumberOfLocals() { ! return types_of_locals.length; ! } ! ! ! public void setTypesOfLocals( final StackMapType[] types ) { ! types_of_locals = types != null ? types : new StackMapType[0]; ! } ! ! ! public StackMapType[] getTypesOfLocals() { ! return types_of_locals; ! } ! ! ! /** ! * ! * @deprecated since 6.0 ! */ ! @java.lang.Deprecated ! public void setNumberOfStackItems( final int n ) { // TODO unused ! } ! ! ! public int getNumberOfStackItems() { ! return types_of_stack_items.length; ! } ! ! ! public void setTypesOfStackItems( final StackMapType[] types ) { ! types_of_stack_items = types != null ? types : new StackMapType[0]; ! } ! ! ! public StackMapType[] getTypesOfStackItems() { ! return types_of_stack_items; ! } ! /** * @return deep copy of this object */ public StackMapEntry copy() { + StackMapEntry e; try { ! e = (StackMapEntry) clone(); ! } catch (final CloneNotSupportedException ex) { ! throw new Error("Clone Not Supported"); ! } ! e.types_of_locals = new StackMapType[types_of_locals.length]; ! for (int i = 0; i < types_of_locals.length; i++) { ! e.types_of_locals[i] = types_of_locals[i].copy(); ! } ! e.types_of_stack_items = new StackMapType[types_of_stack_items.length]; ! for (int i = 0; i < types_of_stack_items.length; i++) { ! e.types_of_stack_items[i] = types_of_stack_items[i].copy(); } + return e; + } + /** * Called by objects that are traversing the nodes of the tree implicitely * defined by the contents of a Java class. I.e., the hierarchy of methods, * fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ ! @Override ! public void accept( final Visitor v ) { v.visitStackMapEntry(this); } + /** * @return Constant pool used by this object. */ ! public final ConstantPool getConstantPool() { ! return constant_pool; ! } ! /** * @param constant_pool Constant pool to be used for this object. */ ! public final void setConstantPool( final ConstantPool constant_pool ) { this.constant_pool = constant_pool; } }
< prev index next >