• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2009 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.optimize.evaluation;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.constant.RefConstant;
25 import proguard.evaluation.BasicInvocationUnit;
26 import proguard.evaluation.value.*;
27 
28 /**
29  * This InvocationUbit loads parameter values and return values that were
30  * previously stored with the methods that are invoked.
31  *
32  * @see StoringInvocationUnit
33  * @author Eric Lafortune
34  */
35 public class LoadingInvocationUnit
36 extends      BasicInvocationUnit
37 {
38     private boolean loadFieldValues;
39     private boolean loadMethodParameterValues;
40     private boolean loadMethodReturnValues;
41 
42 
43     /**
44      * Creates a new LoadingInvocationUnit with the given value factory.
45      */
LoadingInvocationUnit(ValueFactory valueFactory)46     public LoadingInvocationUnit(ValueFactory valueFactory)
47     {
48         this(valueFactory, false, false, false);
49     }
50 
51 
52     /**
53      * Creates a new LoadingInvocationUnit with the given value factory, for
54      * loading the specified values.
55      */
LoadingInvocationUnit(ValueFactory valueFactory, boolean loadFieldValues, boolean loadMethodParameterValues, boolean loadMethodReturnValues)56     public LoadingInvocationUnit(ValueFactory valueFactory,
57                                  boolean      loadFieldValues,
58                                  boolean      loadMethodParameterValues,
59                                  boolean      loadMethodReturnValues)
60     {
61         super(valueFactory);
62 
63         this.loadFieldValues           = loadFieldValues;
64         this.loadMethodParameterValues = loadMethodParameterValues;
65         this.loadMethodReturnValues    = loadMethodReturnValues;
66     }
67 
68 
69     // Implementations for BasicInvocationUnit.
70 
getFieldClassValue(Clazz clazz, RefConstant refConstant, String type)71     protected Value getFieldClassValue(Clazz       clazz,
72                                        RefConstant refConstant,
73                                        String      type)
74     {
75         if (loadFieldValues)
76         {
77             // Do we know this field?
78             Member referencedMember = refConstant.referencedMember;
79             if (referencedMember != null)
80             {
81                 // Retrieve the stored field class value.
82                 ReferenceValue value = StoringInvocationUnit.getFieldClassValue((Field)referencedMember);
83                 if (value != null &&
84                     value.isParticular())
85                 {
86                     return value;
87 //                // Make sure the value is refreshed.
88 //                return refresh(value);
89                 }
90             }
91         }
92 
93         return super.getFieldClassValue(clazz, refConstant, type);
94     }
95 
96 
getFieldValue(Clazz clazz, RefConstant refConstant, String type)97     protected Value getFieldValue(Clazz       clazz,
98                                   RefConstant refConstant,
99                                   String      type)
100     {
101         if (loadFieldValues)
102         {
103             // Do we know this field?
104             Member referencedMember = refConstant.referencedMember;
105             if (referencedMember != null)
106             {
107                 // Retrieve the stored field value.
108                 Value value = StoringInvocationUnit.getFieldValue((Field)referencedMember);
109                 if (value != null &&
110                     value.isParticular())
111                 {
112                     return value;
113 //                // Make sure the value is refreshed.
114 //                return refresh(value);
115                 }
116             }
117         }
118 
119         return super.getFieldValue(clazz, refConstant, type);
120     }
121 
122 
getMethodParameterValue(Clazz clazz, Method method, int parameterIndex, String type, Clazz referencedClass)123     protected Value getMethodParameterValue(Clazz  clazz,
124                                             Method method,
125                                             int    parameterIndex,
126                                             String type,
127                                             Clazz  referencedClass)
128     {
129         if (loadMethodParameterValues)
130         {
131             // Retrieve the stored method parameter value.
132             Value value = StoringInvocationUnit.getMethodParameterValue(method, parameterIndex);
133             if (value != null &&
134                 value.isParticular())
135             {
136                 return value;
137 //            // Make sure the value is refreshed.
138 //            return refresh(value);
139             }
140         }
141 
142         return super.getMethodParameterValue(clazz,
143                                              method,
144                                              parameterIndex,
145                                              type,
146                                              referencedClass);
147     }
148 
149 
getMethodReturnValue(Clazz clazz, RefConstant refConstant, String type)150     protected Value getMethodReturnValue(Clazz       clazz,
151                                          RefConstant refConstant,
152                                          String      type)
153     {
154         if (loadMethodReturnValues)
155         {
156             // Do we know this method?
157             Member referencedMember = refConstant.referencedMember;
158             if (referencedMember != null)
159             {
160                 // Retrieve the stored method return value.
161                 Value value = StoringInvocationUnit.getMethodReturnValue((Method)referencedMember);
162                 if (value != null &&
163                     value.isParticular())
164                 {
165                     return value;
166 //                // Make sure the value is refreshed.
167 //                return refresh(value);
168                 }
169             }
170         }
171 
172         return super.getMethodReturnValue(clazz,
173                                           refConstant,
174                                           type);
175     }
176 //
177 //
178 //    // Small utility methods.
179 //
180 //    private Value refresh(Value value)
181 //    {
182 //        if (value.isParticular())
183 //        {
184 //            return value;
185 //        }
186 //
187 //        switch (value.computationalType())
188 //        {
189 //            case Value.TYPE_INTEGER: return valueFactory.createIntegerValue();
190 //            case Value.TYPE_LONG:    return valueFactory.createLongValue();
191 //            case Value.TYPE_FLOAT:   return valueFactory.createFloatValue();
192 //            case Value.TYPE_DOUBLE:  return valueFactory.createDoubleValue();
193 //            default:
194 //            {
195 //                ReferenceValue referenceValue = value.referenceValue();
196 //
197 //                return valueFactory.createReferenceValue(referenceValue.getType(),
198 //                                                         referenceValue.getReferencedClass(),
199 //                                                         referenceValue.isNull() != Value.NEVER);
200 //            }
201 //        }
202 //    }
203 }
204