Home | History | Annotate | Download | only in editor
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2009 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.editor;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.attribute.*;
     25 import proguard.classfile.attribute.visitor.AttributeVisitor;
     26 import proguard.classfile.instruction.*;
     27 import proguard.classfile.instruction.visitor.InstructionVisitor;
     28 import proguard.classfile.util.*;
     29 
     30 /**
     31  * This AttributeVisitor computes and updates the maximum local variable frame
     32  * size of the code attributes that it visits.
     33  *
     34  * @author Eric Lafortune
     35  */
     36 public class VariableSizeUpdater
     37 extends      SimplifiedVisitor
     38 implements   AttributeVisitor,
     39              InstructionVisitor
     40 {
     41     //*
     42     private static final boolean DEBUG = false;
     43     /*/
     44     private static       boolean DEBUG = true;
     45     //*/
     46 
     47 
     48     // Implementations for AttributeVisitor.
     49 
     50     public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
     51 
     52 
     53     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
     54     {
     55 //        DEBUG =
     56 //            clazz.getName().equals("abc/Def") &&
     57 //            method.getName(clazz).equals("abc");
     58 
     59         // The minimum variable size is determined by the arguments.
     60         codeAttribute.u2maxLocals =
     61             ClassUtil.internalMethodParameterSize(method.getDescriptor(clazz),
     62                                                   method.getAccessFlags());
     63 
     64         if (DEBUG)
     65         {
     66             System.out.println("VariableSizeUpdater: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
     67             System.out.println("  Max locals: "+codeAttribute.u2maxLocals+" <- parameters");
     68         }
     69 
     70         // Go over all instructions.
     71         codeAttribute.instructionsAccept(clazz, method, this);
     72     }
     73 
     74 
     75     // Implementations for InstructionVisitor.
     76 
     77     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
     78 
     79 
     80     public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
     81     {
     82         int variableSize = variableInstruction.variableIndex + 1;
     83         if (variableInstruction.isCategory2())
     84         {
     85             variableSize++;
     86         }
     87 
     88         if (codeAttribute.u2maxLocals < variableSize)
     89         {
     90             codeAttribute.u2maxLocals = variableSize;
     91 
     92             if (DEBUG)
     93             {
     94                 System.out.println("Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset));
     95             }
     96         }
     97     }
     98 }
     99