KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > editor > VariableEditor


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 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.editor;
22
23 import proguard.classfile.*;
24 import proguard.classfile.util.SimplifiedVisitor;
25 import proguard.classfile.attribute.*;
26 import proguard.classfile.attribute.visitor.AttributeVisitor;
27 import proguard.classfile.attribute.annotation.*;
28
29 /**
30  * This AttributeVisitor accumulates specified changes to local variables, and
31  * then applies these accumulated changes to the code attributes that it visits.
32  *
33  * @author Eric Lafortune
34  */

35 public class VariableEditor
36 extends SimplifiedVisitor
37 implements AttributeVisitor
38 {
39     private boolean modified;
40
41     private boolean[] deleted = new boolean[ClassConstants.TYPICAL_VARIABLES_SIZE];
42     private int[] variableMap = new int[ClassConstants.TYPICAL_VARIABLES_SIZE];
43
44     private VariableRemapper variableRemapper = new VariableRemapper();
45
46
47     /**
48      * Resets the accumulated code changes.
49      * @param maxLocals the length of the local variable frame that will be
50      * edited next.
51      */

52     public void reset(int maxLocals)
53     {
54         // Try to reuse the previous array.
55
if (deleted.length < maxLocals)
56         {
57             deleted = new boolean[maxLocals];
58         }
59         else
60         {
61             for (int index = 0; index < maxLocals; index++)
62             {
63                 deleted[index] = false;
64             }
65         }
66
67         modified = false;
68     }
69
70
71     /**
72      * Remembers to delete the given variable.
73      * @param variableIndex the index of the variable to be deleted.
74      */

75     public void deleteVariable(int variableIndex)
76     {
77         deleted[variableIndex] = true;
78
79         modified = true;
80     }
81
82
83     /**
84      * Returns whether the given variable at the given offset has deleted.
85      */

86     public boolean isDeleted(int instructionOffset)
87     {
88         return deleted[instructionOffset];
89     }
90
91
92     // Implementations for AttributeVisitor.
93

94     public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
95
96
97     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
98     {
99         // Avoid doing any work if nothing is changing anyway.
100
if (!modified)
101         {
102             return;
103         }
104
105         int oldMaxLocals = codeAttribute.u2maxLocals;
106
107         // Make sure there is a sufficiently large variable map.
108
if (variableMap.length < oldMaxLocals)
109         {
110             variableMap = new int[oldMaxLocals];
111         }
112
113         // Fill out the variable map.
114
int newVariableIndex = 0;
115         for (int oldVariableIndex = 0; oldVariableIndex < oldMaxLocals; oldVariableIndex++)
116         {
117             if (oldVariableIndex >= deleted.length ||
118                 !deleted[oldVariableIndex])
119             {
120                 variableMap[oldVariableIndex] = newVariableIndex++;
121             }
122             else
123             {
124                 variableMap[oldVariableIndex] = -1;
125             }
126         }
127
128         // Set the map.
129
variableRemapper.setVariableMap(variableMap);
130
131         // Remap the variables.
132
variableRemapper.visitCodeAttribute(clazz, method, codeAttribute);
133
134         // Update the length of local variable frame.
135
codeAttribute.u2maxLocals = newVariableIndex;
136     }
137 }
138
Popular Tags