Home | History | Annotate | Download | only in attribute
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) graphics.cornell.edu)
      6  *
      7  * This program is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by the Free
      9  * Software Foundation; either version 2 of the License, or (at your option)
     10  * any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along
     18  * with this program; if not, write to the Free Software Foundation, Inc.,
     19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  */
     21 package proguard.classfile.attribute;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.attribute.visitor.*;
     25 import proguard.classfile.instruction.*;
     26 import proguard.classfile.instruction.visitor.InstructionVisitor;
     27 
     28 /**
     29  * This Attribute represents a code attribute.
     30  *
     31  * @author Eric Lafortune
     32  */
     33 public class CodeAttribute extends Attribute
     34 {
     35     public int             u2maxStack;
     36     public int             u2maxLocals;
     37     public int             u4codeLength;
     38     public byte[]          code;
     39     public int             u2exceptionTableLength;
     40     public ExceptionInfo[] exceptionTable;
     41     public int             u2attributesCount;
     42     public Attribute[]     attributes;
     43 
     44 
     45     /**
     46      * Creates an uninitialized CodeAttribute.
     47      */
     48     public CodeAttribute()
     49     {
     50     }
     51 
     52 
     53     /**
     54      * Creates an initialized CodeAttribute.
     55      */
     56     public CodeAttribute(int             u2attributeNameIndex,
     57                          int             u2maxStack,
     58                          int             u2maxLocals,
     59                          int             u4codeLength,
     60                          byte[]          code,
     61                          int             u2exceptionTableLength,
     62                          ExceptionInfo[] exceptionTable,
     63                          int             u2attributesCount,
     64                          Attribute[]     attributes)
     65     {
     66         super(u2attributeNameIndex);
     67 
     68         this.u2maxStack             = u2maxStack;
     69         this.u2maxLocals            = u2maxLocals;
     70         this.u4codeLength           = u4codeLength;
     71         this.code                   = code;
     72         this.u2exceptionTableLength = u2exceptionTableLength;
     73         this.exceptionTable         = exceptionTable;
     74         this.u2attributesCount      = u2attributesCount;
     75         this.attributes             = attributes;
     76     }
     77 
     78 
     79     /**
     80      * Returns the (first) attribute with the given name.
     81      */
     82     public Attribute getAttribute(Clazz clazz, String name)
     83     {
     84         for (int index = 0; index < u2attributesCount; index++)
     85         {
     86             Attribute attribute = attributes[index];
     87             if (attribute.getAttributeName(clazz).equals(name))
     88             {
     89                 return attribute;
     90             }
     91         }
     92 
     93         return null;
     94     }
     95 
     96 
     97     // Implementations for Attribute.
     98 
     99     public void accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
    100     {
    101         attributeVisitor.visitCodeAttribute(clazz, method, this);
    102     }
    103 
    104 
    105     /**
    106      * Applies the given instruction visitor to all instructions.
    107      */
    108     public void instructionsAccept(Clazz clazz, Method method, InstructionVisitor instructionVisitor)
    109     {
    110         instructionsAccept(clazz, method, 0, u4codeLength, instructionVisitor);
    111     }
    112 
    113 
    114     /**
    115      * Applies the given instruction visitor to the instruction at the specified
    116      * offset.
    117      */
    118     public void instructionAccept(Clazz clazz, Method method, int offset, InstructionVisitor instructionVisitor)
    119     {
    120         Instruction instruction = InstructionFactory.create(code, offset);
    121         instruction.accept(clazz, method, this, offset, instructionVisitor);
    122     }
    123 
    124 
    125     /**
    126      * Applies the given instruction visitor to all instructions in the
    127      * specified range of offsets.
    128      */
    129     public void instructionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, InstructionVisitor instructionVisitor)
    130     {
    131         int offset = startOffset;
    132 
    133         while (offset < endOffset)
    134         {
    135             // Note that the instruction is only volatile.
    136             Instruction instruction = InstructionFactory.create(code, offset);
    137             int instructionLength = instruction.length(offset);
    138             instruction.accept(clazz, method, this, offset, instructionVisitor);
    139             offset += instructionLength;
    140         }
    141     }
    142 
    143 
    144     /**
    145      * Applies the given exception visitor to all exceptions.
    146      */
    147     public void exceptionsAccept(Clazz clazz, Method method, ExceptionInfoVisitor exceptionInfoVisitor)
    148     {
    149         for (int index = 0; index < u2exceptionTableLength; index++)
    150         {
    151             // We don't need double dispatching here, since there is only one
    152             // type of ExceptionInfo.
    153             exceptionInfoVisitor.visitExceptionInfo(clazz, method, this, exceptionTable[index]);
    154         }
    155     }
    156 
    157 
    158     /**
    159      * Applies the given exception visitor to all exceptions that are applicable
    160      * to the instruction at the specified offset.
    161      */
    162     public void exceptionsAccept(Clazz clazz, Method method, int offset, ExceptionInfoVisitor exceptionInfoVisitor)
    163     {
    164         for (int index = 0; index < u2exceptionTableLength; index++)
    165         {
    166             ExceptionInfo exceptionInfo = exceptionTable[index];
    167             if (exceptionInfo.isApplicable(offset))
    168             {
    169                 exceptionInfoVisitor.visitExceptionInfo(clazz, method, this, exceptionInfo);
    170             }
    171         }
    172     }
    173 
    174 
    175     /**
    176      * Applies the given exception visitor to all exceptions that are applicable
    177      * to any of the instructions in the specified range of offsets.
    178      */
    179     public void exceptionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, ExceptionInfoVisitor exceptionInfoVisitor)
    180     {
    181         for (int index = 0; index < u2exceptionTableLength; index++)
    182         {
    183             ExceptionInfo exceptionInfo = exceptionTable[index];
    184             if (exceptionInfo.isApplicable(startOffset, endOffset))
    185             {
    186                 exceptionInfoVisitor.visitExceptionInfo(clazz, method, this, exceptionInfo);
    187             }
    188         }
    189     }
    190 
    191 
    192     /**
    193      * Applies the given attribute visitor to all attributes.
    194      */
    195     public void attributesAccept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)
    196     {
    197         for (int index = 0; index < u2attributesCount; index++)
    198         {
    199             attributes[index].accept(clazz, method, this, attributeVisitor);
    200         }
    201     }
    202 }
    203