• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2013 Eric Lafortune (eric@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      */
CodeAttribute()48     public CodeAttribute()
49     {
50     }
51 
52 
53     /**
54      * Creates an initialized CodeAttribute.
55      */
CodeAttribute(int u2attributeNameIndex, int u2maxStack, int u2maxLocals, int u4codeLength, byte[] code, int u2exceptionTableLength, ExceptionInfo[] exceptionTable, int u2attributesCount, Attribute[] attributes)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      */
getAttribute(Clazz clazz, String name)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 
accept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)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      */
instructionsAccept(Clazz clazz, Method method, InstructionVisitor instructionVisitor)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      */
instructionAccept(Clazz clazz, Method method, int offset, InstructionVisitor instructionVisitor)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      */
instructionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, InstructionVisitor instructionVisitor)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      */
exceptionsAccept(Clazz clazz, Method method, ExceptionInfoVisitor exceptionInfoVisitor)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      */
exceptionsAccept(Clazz clazz, Method method, int offset, ExceptionInfoVisitor exceptionInfoVisitor)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      */
exceptionsAccept(Clazz clazz, Method method, int startOffset, int endOffset, ExceptionInfoVisitor exceptionInfoVisitor)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      */
attributesAccept(Clazz clazz, Method method, AttributeVisitor attributeVisitor)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