Home | History | Annotate | Download | only in evaluation
      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.optimize.evaluation;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.constant.RefConstant;
     25 import proguard.evaluation.BasicInvocationUnit;
     26 import proguard.evaluation.value.*;
     27 import proguard.optimize.info.*;
     28 
     29 /**
     30  * This InvocationUnit stores parameter values and return values with the
     31  * methods that are invoked.
     32  *
     33  * @see LoadingInvocationUnit
     34  * @author Eric Lafortune
     35  */
     36 public class StoringInvocationUnit
     37 extends      BasicInvocationUnit
     38 {
     39     private boolean storeFieldValues;
     40     private boolean storeMethodParameterValues;
     41     private boolean storeMethodReturnValues;
     42 
     43 
     44     /**
     45      * Creates a new StoringInvocationUnit with the given value factory.
     46      */
     47     public StoringInvocationUnit(ValueFactory valueFactory)
     48     {
     49         this(valueFactory, true, true, true);
     50     }
     51 
     52 
     53     /**
     54      * Creates a new StoringInvocationUnit with the given value factory, for
     55      * storing the specified values.
     56      */
     57     public StoringInvocationUnit(ValueFactory valueFactory,
     58                                  boolean      storeFieldValues,
     59                                  boolean      storeMethodParameterValues,
     60                                  boolean      storeMethodReturnValues)
     61     {
     62         super(valueFactory);
     63 
     64         this.storeFieldValues           = storeFieldValues;
     65         this.storeMethodParameterValues = storeMethodParameterValues;
     66         this.storeMethodReturnValues    = storeMethodReturnValues;
     67     }
     68 
     69 
     70     // Implementations for BasicInvocationUnit.
     71 
     72     protected void setFieldClassValue(Clazz          clazz,
     73                                       RefConstant    refConstant,
     74                                       ReferenceValue value)
     75     {
     76         if (storeFieldValues)
     77         {
     78             Member referencedMember = refConstant.referencedMember;
     79             if (referencedMember != null)
     80             {
     81                 generalizeFieldClassValue((Field)referencedMember, value);
     82             }
     83         }
     84     }
     85 
     86 
     87     protected void setFieldValue(Clazz       clazz,
     88                                  RefConstant refConstant,
     89                                  Value       value)
     90     {
     91         if (storeFieldValues)
     92         {
     93             Member referencedMember = refConstant.referencedMember;
     94             if (referencedMember != null)
     95             {
     96                 generalizeFieldValue((Field)referencedMember, value);
     97             }
     98         }
     99     }
    100 
    101 
    102     protected void setMethodParameterValue(Clazz       clazz,
    103                                            RefConstant refConstant,
    104                                            int         parameterIndex,
    105                                            Value       value)
    106     {
    107         if (storeMethodParameterValues)
    108         {
    109             Member referencedMember = refConstant.referencedMember;
    110             if (referencedMember != null)
    111             {
    112                 generalizeMethodParameterValue((Method)referencedMember,
    113                                                parameterIndex,
    114                                                value);
    115             }
    116         }
    117     }
    118 
    119 
    120     protected void setMethodReturnValue(Clazz  clazz,
    121                                         Method method,
    122                                         Value  value)
    123     {
    124         if (storeMethodReturnValues)
    125         {
    126             generalizeMethodReturnValue(method, value);
    127         }
    128     }
    129 
    130 
    131     // Small utility methods.
    132 
    133     private static void generalizeFieldClassValue(Field field, ReferenceValue value)
    134     {
    135         FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
    136         if (info != null)
    137         {
    138             info.generalizeReferencedClass(value);
    139         }
    140     }
    141 
    142 
    143     public static ReferenceValue getFieldClassValue(Field field)
    144     {
    145         FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
    146         return info != null ?
    147             info.getReferencedClass() :
    148             null;
    149     }
    150 
    151 
    152     private static void generalizeFieldValue(Field field, Value value)
    153     {
    154         FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
    155         if (info != null)
    156         {
    157             info.generalizeValue(value);
    158         }
    159     }
    160 
    161 
    162     public static Value getFieldValue(Field field)
    163     {
    164         FieldOptimizationInfo info = FieldOptimizationInfo.getFieldOptimizationInfo(field);
    165         return info != null ?
    166             info.getValue() :
    167             null;
    168     }
    169 
    170 
    171     private static void generalizeMethodParameterValue(Method method, int parameterIndex, Value value)
    172     {
    173         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
    174         if (info != null)
    175         {
    176             info.generalizeParameter(parameterIndex, value);
    177         }
    178     }
    179 
    180 
    181     public static Value getMethodParameterValue(Method method, int parameterIndex)
    182     {
    183         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
    184         return info != null ?
    185             info.getParameter(parameterIndex) :
    186             null;
    187     }
    188 
    189 
    190     private static void generalizeMethodReturnValue(Method method, Value value)
    191     {
    192         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
    193         if (info != null)
    194         {
    195             info.generalizeReturnValue(value);
    196         }
    197     }
    198 
    199 
    200     public static Value getMethodReturnValue(Method method)
    201     {
    202         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(method);
    203         return info != null ?
    204             info.getReturnValue() :
    205             null;
    206     }
    207 }
    208