[ 
https://issues.apache.org/jira/browse/BCEL-202?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14395240#comment-14395240
 ] 

Daniel Stuber commented on BCEL-202:
------------------------------------

Some more work needs to be done for allowing users to adjust a method's 
stack-map-table.

Some entry-types have their offset-delta stored in the frame-type. Thus 
altering the offset-delta may need altering the frame-type, too. It can 
therefore not be final any more. I also suggest to reduce the visibility of the 
method to package-private.
StackMapTableEntry.java:
    int calculateLength() {
      if (frame_type >= Constants.SAME_FRAME && frame_type <= 
Constants.SAME_FRAME_MAX) {
        return 1;
      } else if (frame_type >= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME && 
frame_type <= Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) {
          return 1 + (types_of_stack_items[0].hasIndex() ? 3 : 1);
      } else if (frame_type == 
Constants.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
          return 3 + (types_of_stack_items[0].hasIndex() ? 3 : 1);
      } else if (frame_type >= Constants.CHOP_FRAME && frame_type <= 
Constants.CHOP_FRAME_MAX) {
        return 3;
      } else if (frame_type == Constants.SAME_FRAME_EXTENDED) {
        return 3;
      } else if (frame_type >= Constants.APPEND_FRAME && frame_type <= 
Constants.APPEND_FRAME_MAX) {
        int len = 3;
          for (int i = 0; i < types_of_locals.length; i++) {
              len += types_of_locals[i].hasIndex() ? 3 : 1;
          }
          return len;
      } else if (frame_type == Constants.FULL_FRAME) {        
        int len = 7;
          for (int i = 0; i < types_of_locals.length; i++) {
              len += types_of_locals[i].hasIndex() ? 3 : 1;
          }
          for (int i = 0; i < types_of_stack_items.length; i++) {
              len += types_of_stack_items[i].hasIndex() ? 3 : 1;
          }
          return len;
      } else {
          /* Can't happen */
          throw new ClassFormatException ("Invalid Stack map table tag: " + 
frame_type);
      }
    }


Furthermore it might be necessary to completely replace a stack-map-entry with 
another element resulting in a different length of the whole stack-map-table. I 
do this as follows:
StackMapTable.java
    public final void setStackMapTable( StackMapTableEntry[] map ) {
        this.map = map;

        int len = 2;
        for (int i = 0; i < map.length; i++) {
          len += map[i].calculateLength();
        }
        setLength(len);
    }

This enforces a slight change in one constructor by directly setting the map 
variable rather than calling setStackMapTable():
    public StackMapTable(int name_index, int length, StackMapTableEntry[] map, 
ConstantPool constant_pool) {
        super(Constants.ATTR_STACK_MAP_TABLE, name_index, length, 
constant_pool);
        this.map = map;
    }


> StackMapTableEntry.copy() needs to be deep; Improved support for StackMaps
> --------------------------------------------------------------------------
>
>                 Key: BCEL-202
>                 URL: https://issues.apache.org/jira/browse/BCEL-202
>             Project: Commons BCEL
>          Issue Type: Bug
>            Reporter: Mark Roberts
>         Attachments: stackmap.diff
>
>
> There are several ways a user can modify a Java class file that should cause 
> BCEL to update the StackMaps automatically.  Unfortunately, it does not.  
> These additional methods at least allow users to take care of these issues 
> for themselves.
> The patch also fixes a bug - StackMapTableEntry.copy() needs to be a deep 
> copy to prevent StackMapTypes from being reused.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to