Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /* Soot - a J*va Optimization Framework
    * Copyright (C) 1997 Clark Verbrugge
    *
    * This library is free software; you can redistribute it and/or
    * modify it under the terms of the GNU Lesser General Public
    * License as published by the Free Software Foundation; either
    * version 2.1 of the License, or (at your option) any later version.
    *
    * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 02111-1307, USA.
   */
  
  /*
   * Modified by the Sable Research Group and others 1997-1999.  
   * See the 'credits' file distributed with Soot for the complete list of
   * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
   */
  
  
  
  
  
  
  
  package soot.coffi;
  import soot.jimple.*;
  import java.util.*;
  import java.io.*;
  import soot.tagkit.*;
  import soot.*;
  
  
  public class Util
  {
      public UtilSingletons.Global g ) {}
      public static Util v() { return G.v().soot_coffi_Util(); }
  
  
      Set markedClasses;
  
      int activeOriginalIndex = -1;
      cp_info[] activeConstantPool = null;
      boolean useFaithfulNaming = false;
      boolean isLocalStore = false;  // global variable used 
      boolean isWideLocalStore = false;
      public void setFaithfulNaming(boolean v)
      {
           = v;
      }    
  
      public void resolveFromClassFile(SootClass aClassInputStream isList references)
      {
          SootClass bclass = aClass;                
          String className = bclass.getName();
          ClassFile coffiClass = new ClassFile(className);
          
          // Load up class file, and retrieve bclass from class manager.
          {
              boolean success = coffiClass.loadClassFile(is);
  
              if(!success)
                  {
                      if(!Scene.v().allowsPhantomRefs())
                          throw new RuntimeException("Could not load classfile: " + bclass.getName());
                      else {                        
                          G.v()..println("Warning: " + className + " is a phantom class!");
                          bclass.setPhantom(true);                                                                
                          return;
                      } 
                      
                  }
              
              CONSTANT_Class_info c = (CONSTANT_Class_infocoffiClass.constant_pool[coffiClass.this_class];
      
              String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
              name = name.replace('/''.');
                  	    
              if( !name.equalsbclass.getName() ) ) {
                  throw new RuntimeException
                          "Error: class "+name+" read in from a classfile in which "+bclass.getName()+" was expected." );
              }
          }
        
          // Set modifier
          bclass.setModifiers(coffiClass.access_flags & (~0x0020));
          // don't want the ACC_SUPER flag, it is always supposed to be set anyways
      
          // Set superclass
         {
             if(coffiClass.super_class != 0)
                 {
                     // This object is not java.lang.Object, so must have a super class
                     
                     CONSTANT_Class_info c = (CONSTANT_Class_infocoffiClass.constant_pool[coffiClass.super_class];
     
                     String superName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
                     superName = superName.replace('/''.');
     
                     references.add(superName);
                     bclass.setSuperclass(SootResolver.v().makeClassRef(superName));
                 }
         }
     
         // Add interfaces to the bclass
         {
             for(int i = 0; i < coffiClass.interfaces_counti++)
                 {
                     CONSTANT_Class_info c = (CONSTANT_Class_infocoffiClass.constant_pool[coffiClass.interfaces[i]];
     
                     String interfaceName =
                         ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
     
                     interfaceName = interfaceName.replace('/''.');
     
                     references.add(interfaceName);
                     SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceName);
                     bclass.addInterface(interfaceClass);
                 }
         }
     
         // Add every field to the bclass
         for(int i = 0; i < coffiClass.fields_counti++){
             
             field_info fieldInfo = coffiClass.fields[i];
 
             String fieldName = ((CONSTANT_Utf8_info)
                                 (coffiClass.constant_pool[fieldInfo.name_index])).convert();
 
             String fieldDescriptor = ((CONSTANT_Utf8_info)
                                       (coffiClass.constant_pool[fieldInfo.descriptor_index])).convert();
 
             int modifiers = fieldInfo.access_flags;
             Type fieldType = jimpleTypeOfFieldDescriptor(fieldDescriptor);
                 
             SootField field = new SootField(fieldNamefieldTypemodifiers);
             bclass.addField(field);
                 
             references.add(fieldType);
 
             // add initialization constant, if any
 		    for(int j = 0; j < fieldInfo.attributes_countj++) {
                 // add constant value attributes
                 if (fieldInfo.attributes[jinstanceof ConstantValue_attribute){
                     
                     ConstantValue_attribute attr = (ConstantValue_attributefieldInfo.attributes[j];
                     cp_info cval = coffiClass.constant_pool[attr.constantvalue_index];
                     ConstantValueTag tag;
                     switch (cval.tag) {
                     case .:
                     tag = new IntegerConstantValueTag((int)((CONSTANT_Integer_info)cval).);
                     break;
                     case .:
                     //tag = new FloatConstantValueTag((int)((CONSTANT_Float_info)cval).bytes);
                     tag = new FloatConstantValueTag(((CONSTANT_Float_info)cval).convert());
                     break;
                     case .:
                       {
                     CONSTANT_Long_info lcval = (CONSTANT_Long_info)cval;
                     tag = new LongConstantValueTag((lcval.high << 32) + lcval.low);
                     break;
                       }
                     case .:
                       {
                     CONSTANT_Double_info dcval = (CONSTANT_Double_info)cval;
                     //tag = new DoubleConstantValueTag((dcval.high << 32) + dcval.low);
                     tag = new DoubleConstantValueTag(dcval.convert());
                     break;
                       }
                     case .:
                       {
                     CONSTANT_String_info scval = (CONSTANT_String_info)cval;
                     CONSTANT_Utf8_info ucval = (CONSTANT_Utf8_info)coffiClass.constant_pool[scval.string_index];
                     tag = new StringConstantValueTag(ucval.convert());
                     break;
                       }
                     default:
                     throw new RuntimeException("unexpected ConstantValue: " + cval);
                     }
                     field.addTag(tag);
                 }
                 // add synthetic tag
                 else if (fieldInfo.attributes[jinstanceof Synthetic_attribute){
                     field.addTag(new SyntheticTag());
                 }
                 // add deprecated tag
                 else if (fieldInfo.attributes[jinstanceof Deprecated_attribute){
                     field.addTag(new DeprecatedTag());
                 }
                 // add signature tag
                 else if (fieldInfo.attributes[jinstanceof Signature_attribute){
                     String generic_sig = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[((Signature_attribute)fieldInfo.attributes[j]).])).convert();
                     field.addTag(new SignatureTag(generic_sig));
                 }
                 else if (fieldInfo.attributes[jinstanceof RuntimeVisibleAnnotations_attribute || fieldInfo.attributes[jinstanceof RuntimeInvisibleAnnotations_attribute)
                 {
                     addAnnotationVisibilityAttribute(fieldfieldInfo.attributes[j], coffiClassreferences);
                 }
                 else if (fieldInfo.attributes[jinstanceof Generic_attribute)
                 {        	
                 	Generic_attribute attr = (Generic_attributefieldInfo.attributes[j];
                     String name = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[attr.attribute_name])).convert();
         			field.addTag(new GenericAttribute(nameattr.info));
                 }
 		    }
         }
     
         // Add every method to the bclass
         for(int i = 0; i < coffiClass.methods_counti++){
             
             method_info methodInfo = coffiClass.methods[i];
 		
 		
 		    if( (coffiClass.constant_pool[methodInfo.name_index]) == null) {
 		        G.v()..println("method index: " + methodInfo.toName(coffiClass.constant_pool));
 		        throw new RuntimeException("method has no name");
 		    }
 
             String methodName = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[methodInfo.name_index])).convert();
 		    String methodDescriptor = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[methodInfo.descriptor_index])).convert();
     
             List parameterTypes;
             Type returnType;
     
             // Generate parameterTypes & returnType
             {
                 Type[] types = jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor);
     
                 parameterTypes = new ArrayList();
                 for(int j = 0; j < types.length - 1; j++){
                     references.add(types[j]);
                     parameterTypes.add(types[j]);
                 }
                         
                 returnType = types[types.length - 1];
                 references.add(returnType);
             }
     
             int modifiers = methodInfo.access_flags;
 
             SootMethod method;
 
             method = new SootMethod(methodName,
                                     parameterTypesreturnTypemodifiers);
             bclass.addMethod(method);
 
             methodInfo.jmethod = method;
 
             // add exceptions to method
             {
                 for(int j = 0; j < methodInfo.attributes_countj++){
                     if(methodInfo.attributes[jinstanceof Exception_attribute){
                         Exception_attribute exceptions = (Exception_attributemethodInfo.attributes[j];
 
                         for(int k = 0; k < exceptions.number_of_exceptionsk++)
 {
                             CONSTANT_Class_info c = (CONSTANT_Class_infocoffiClass.
                             constant_pool[exceptions.exception_index_table[k]];
 
                             String exceptionName = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[c.name_index])).convert();
 
                             exceptionName = exceptionName.replace('/''.');
 
                             references.add(exceptionName);
                             method.addExceptionIfAbsent(SootResolver.v().makeClassRef(exceptionName));
                         }
                     }
                     else if (methodInfo.attributes[jinstanceof Synthetic_attribute) {
                         method.addTag(new SyntheticTag());
                     }
                     else if (methodInfo.attributes[jinstanceof Deprecated_attribute) {
                         method.addTag(new DeprecatedTag());
                     }
                     else if (methodInfo.attributes[jinstanceof Signature_attribute){
                         String generic_sig = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[((Signature_attribute)methodInfo.attributes[j]).])).convert();
                         method.addTag(new SignatureTag(generic_sig));
                     }
                     else if (methodInfo.attributes[jinstanceof RuntimeVisibleAnnotations_attribute || methodInfo.attributes[jinstanceof RuntimeInvisibleAnnotations_attribute)
                     {
                         addAnnotationVisibilityAttribute(methodmethodInfo.attributes[j], coffiClassreferences);
                     }
                     else if (methodInfo.attributes[jinstanceof RuntimeVisibleParameterAnnotations_attribute || methodInfo.attributes[jinstanceof RuntimeInvisibleParameterAnnotations_attribute)
                     {
                         addAnnotationVisibilityParameterAttribute(methodmethodInfo.attributes[j], coffiClassreferences);
                     }
                     else if (methodInfo.attributes[jinstanceof AnnotationDefault_attribute)
                     {
                         AnnotationDefault_attribute attr = (AnnotationDefault_attribute)methodInfo.attributes[j];
                         element_value [] input = new element_value[1];
                         input[0] = attr.default_value;
                         ArrayList<AnnotationElemlist = createElementTags(1, coffiClassinput);
                         method.addTag(new AnnotationDefaultTag(list.get(0)));
                     }
                     else if (methodInfo.attributes[jinstanceof Generic_attribute)
                     {        	
                     	Generic_attribute attr = (Generic_attributemethodInfo.attributes[j];
                         String name = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[attr.attribute_name])).convert();
             			method.addTag(new GenericAttribute(nameattr.info));
                     }
                 }
             }
                     
                 // Go through the constant pool, forcing all mentioned classes to be resolved. 
                 {
                     for(int k = 0; k < coffiClass.constant_pool_countk++) {
                         if(coffiClass.constant_pool[kinstanceof CONSTANT_Class_info)
                             {
                                 CONSTANT_Class_info c = (CONSTANT_Class_infocoffiClass.constant_pool[k];
 
                                 String desc = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
                                 String name = desc.replace('/''.');
 
                                 if(name.startsWith("["))
                                     references.add(jimpleTypeOfFieldDescriptor(desc));
                                 else
                                     references.add(name);
                             }
                         if(coffiClass.constant_pool[kinstanceof CONSTANT_Fieldref_info
                         || coffiClass.constant_pool[kinstanceof CONSTANT_Methodref_info
                         || coffiClass.constant_pool[kinstanceof CONSTANT_InterfaceMethodref_info) {
                             Type[] types = jimpleTypesOfFieldOrMethodDescriptor(
                                 cp_info.getTypeDescr(coffiClass.constant_pool,k));
                             for (Type element : types) {
                                 references.add(element);
                             }
                         }
 
                     }
                 }
             }
 
         // Set coffi source of method
         for(int i = 0; i < coffiClass.methods_counti++)
             {
                 method_info methodInfo = coffiClass.methods[i];
                 //                methodInfo.jmethod.setSource(coffiClass, methodInfo);
                 methodInfo.jmethod.setSource(new CoffiMethodSource(coffiClassmethodInfo));
             }
         
 	// Set "SourceFile" attribute tag
 	for(int i = 0; i < coffiClass.attributes_counti++){
 	    
 		if(coffiClass.attributes[iinstanceof SourceFile_attribute){
 		    
 		    SourceFile_attribute attr = (SourceFile_attribute)coffiClass.attributes[i];
             String sourceFile = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[attr.sourcefile_index])).convert();
 
             ifsourceFile.indexOf(' ') >= 0 ) {
                 G.v()..println"Warning: Class "+className+" has invalid SourceFile attribute (will be ignored)." );
             } else {
                 bclass.addTag(new SourceFileTagsourceFile ) );
             }
 	
 	    }
 	    // Set "InnerClass" attribute tag
 	    else if(coffiClass.attributes[iinstanceof InnerClasses_attribute){
 		   
 		    InnerClasses_attribute attr = (InnerClasses_attribute)coffiClass.attributes[i];
             for (int j = 0; j < attr.inner_classes_lengthj++)
                 {
                     inner_class_entry e = attr.inner_classes[j];
                 String inner = null;
                 String outer = null;
                 String name = null;
                 if (e.inner_class_index != 0)
                     inner = ((CONSTANT_Utf8_info)coffiClass.constant_pool[((CONSTANT_Class_info)coffiClass.constant_pool[e.inner_class_index]).]).convert();
                 if (e.outer_class_index != 0)
                     outer = ((CONSTANT_Utf8_info)coffiClass.constant_pool[((CONSTANT_Class_info)coffiClass.constant_pool[e.outer_class_index]).]).convert();
                 if (e.name_index != 0)
                     name = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[e.name_index])).convert();
                 bclass.addTag(new InnerClassTag(innerouternamee.access_flags));
             }
         }
         // set synthetic tags
         else if(coffiClass.attributes[iinstanceof Synthetic_attribute){
 		    
 		    bclass.addTag(new SyntheticTag());
         }
         // set deprectaed tags
         else if(coffiClass.attributes[iinstanceof Deprecated_attribute){
 		    
 		    bclass.addTag(new DeprecatedTag());
         }
         else if (coffiClass.attributes[iinstanceof Signature_attribute){
             String generic_sig = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[((Signature_attribute)coffiClass.attributes[i]).])).convert();
             bclass.addTag(new SignatureTag(generic_sig));
         }
         else if (coffiClass.attributes[iinstanceof EnclosingMethod_attribute){           
             EnclosingMethod_attribute attr = (EnclosingMethod_attribute)coffiClass.attributes[i];
             String class_name = ((CONSTANT_Utf8_info)coffiClass.constant_pool[((CONSTANT_Class_info)coffiClass.constant_poolattr.class_index  ]).]).convert();
             CONSTANT_NameAndType_info info = (CONSTANT_NameAndType_info)coffiClass.constant_pool[attr.method_index];
 
             String method_name = "";
             String method_sig = "";
             
             if (info != null){
                 method_name = ((CONSTANT_Utf8_info)coffiClass.constant_pool[info.name_index]).convert();
                 method_sig = ((CONSTANT_Utf8_info)coffiClass.constant_pool[info.descriptor_index]).convert();
             }
             bclass.addTag(new EnclosingMethodTag(class_namemethod_namemethod_sig));
         }
         else if (coffiClass.attributes[iinstanceof RuntimeVisibleAnnotations_attribute || coffiClass.attributes[iinstanceof RuntimeInvisibleAnnotations_attribute)
         {
             addAnnotationVisibilityAttribute(bclasscoffiClass.attributes[i], coffiClassreferences);
         }
         else if (coffiClass.attributes[iinstanceof Generic_attribute)
         {        	
         	Generic_attribute attr = (Generic_attributecoffiClass.attributes[i];
             String name = ((CONSTANT_Utf8_info)(coffiClass.constant_pool[attr.attribute_name])).convert();
 			bclass.addTag(new GenericAttribute(nameattr.info));
         }
    
     }
     }
 
 
 
     {
         Type[] types = jimpleTypesOfFieldOrMethodDescriptor(descriptor);
 
         return types[types.length - 1];
     }
 
     private final ArrayList<TypeconversionTypes = new ArrayList<Type>();
     
     /*
     private Map cache = new HashMap();
     public Type[] jimpleTypesOfFieldOrMethodDescriptor(String descriptor)
     {
         Type[] ret = (Type[]) cache.get(descriptor);
         if( ret != null ) return ret;
         conversionTypes.clear();
 
         while(descriptor.length() != 0)
         {
             boolean isArray = false;
             int numDimensions = 0;
             Type baseType;
 
             // Skip parenthesis
                 if(descriptor.startsWith("(") || descriptor.startsWith(")"))
                 {
                     descriptor = descriptor.substring(1);
                     continue;
                 }
 
             // Handle array case
                 while(descriptor.startsWith("["))
                 {
                     isArray = true;
                     numDimensions++;
                     descriptor = descriptor.substring(1);
                 }
 
             // Determine base type
                 if(descriptor.startsWith("B"))
                 {
                     baseType = ByteType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("C"))
                 {
                     baseType = CharType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("D"))
                 {
                     baseType = DoubleType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("F"))
                 {
                     baseType = FloatType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("I"))
                 {
                     baseType = IntType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("J"))
                 {
                     baseType = LongType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("L"))
                 {
                     int index = descriptor.indexOf(';');
 
                     if(index == -1)
                         throw new RuntimeException("Class reference has no ending ;");
 
                     String className = descriptor.substring(1, index);
 
                     baseType = RefType.v(className.replace('/', '.'));
 
                     descriptor = descriptor.substring(index + 1);
                 }
                 else if(descriptor.startsWith("S"))
                 {
                     baseType = ShortType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("Z"))
                 {
                     baseType = BooleanType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else if(descriptor.startsWith("V"))
                 {
                     baseType = VoidType.v();
                     descriptor = descriptor.substring(1);
                 }
                 else
                     throw new RuntimeException("Unknown field type!");
 
             Type t;
 
             // Determine type
                 if(isArray)
                     t = ArrayType.v(baseType, numDimensions);
                 else
                     t = baseType;
 
             conversionTypes.add(t);
         }
 
         ret = (Type[]) conversionTypes.toArray(new Type[0]);
         cache.put(descriptor, ret);
         return ret;
     }
 */
 
 
     private final Map<StringType[]> cache = new HashMap<StringType[]>();
     public Type[] jimpleTypesOfFieldOrMethodDescriptor(String descriptor)
     {
         Type[] ret = .get(descriptor);
         ifret != null ) return ret;
         char[] d = descriptor.toCharArray();
         int p = 0;
         .clear();
 
 outer:
         while(p<d.length)
         {
             boolean isArray = false;
             int numDimensions = 0;
             Type baseType = null;
 
 swtch:
             while(p<d.length) {
                 switchd[p] ) {
                 // Skip parenthesis
                     case '('case ')':
                         p++;
                         continue outer;
 
                     case '[':
                         isArray = true;
                         numDimensions++;
                         p++;
                         continue swtch;
                     case 'B':
                         baseType = ByteType.v();
                         p++;
                         break swtch;
                     case 'C':
                         baseType = CharType.v();
                         p++;
                         break swtch;
                     case 'D':
                         baseType = DoubleType.v();
                         p++;
                         break swtch;
                     case 'F':
                         baseType = FloatType.v();
                         p++;
                         break swtch;
                     case 'I':
                         baseType = IntType.v();
                         p++;
                         break swtch;
                     case 'J':
                         baseType = LongType.v();
                         p++;
                         break swtch;
                     case 'L':
                         int index = p+1;
                         while(index < d.length && d[index] != ';') {
                             if(d[index] == '/'d[index] = '.';
                             index++;
                         }
                         ifindex >= d.length )
                             throw new RuntimeException("Class reference has no ending ;");
                         String className = new String(dp+1, index - p - 1);
                         baseType = RefType.v(className);
                         p = index+1;
                         break swtch;
                     case 'S':
                         baseType = ShortType.v();
                         p++;
                         break swtch;
                     case 'Z':
                         baseType = BooleanType.v();
                         p++;
                         break swtch;
                     case 'V':
                         baseType = VoidType.v();
                         p++;
                         break swtch;
                     default:
                         throw new RuntimeException("Unknown field type!");
                 }
             }
             ifbaseType == null ) continue;
 
             // Determine type
             Type t;
             if(isArray)
                 t = ArrayType.v(baseTypenumDimensions);
             else
                 t = baseType;
 
             .add(t);
         }
 
         ret = .toArray(new Type[0]);
         .put(descriptorret);
         return ret;
     }
 
     public Type jimpleTypeOfFieldDescriptor(String descriptor)
     {
         boolean isArray = false;
         int numDimensions = 0;
         Type baseType;
 
         // Handle array case
             while(descriptor.startsWith("["))
             {
                 isArray = true;
                 numDimensions++;
                 descriptor = descriptor.substring(1);
             }
 
         // Determine base type
             if(descriptor.equals("B"))
                 baseType = ByteType.v();
             else if(descriptor.equals("C"))
                 baseType = CharType.v();
             else if(descriptor.equals("D"))
                 baseType = DoubleType.v();
             else if(descriptor.equals("F"))
                 baseType = FloatType.v();
             else if(descriptor.equals("I"))
                 baseType = IntType.v();
             else if(descriptor.equals("J"))
                 baseType = LongType.v();
             else if(descriptor.equals("V"))
                 baseType = VoidType.v();
             else if(descriptor.startsWith("L"))
             {
                 if(!descriptor.endsWith(";"))
                     throw new RuntimeException("Class reference does not end with ;");
 
                 String className = descriptor.substring(1, descriptor.length() - 1);
 
                 baseType = RefType.v(className.replace('/''.'));
             }
             else if(descriptor.equals("S"))
                 baseType = ShortType.v();
             else if(descriptor.equals("Z"))
                 baseType = BooleanType.v();
             else
                 throw new RuntimeException("Unknown field type: " + descriptor);
 
         // Return type
             if(isArray)
                 return ArrayType.v(baseTypenumDimensions);
             else
                 return baseType;
     }
 
     int nextEasyNameIndex;
 
     void resetEasyNames()
     {
          = 0;
     }
 
     {
         final String[] easyNames =
             {"a""b""c""d""e""f""g""h""i""j""k""l""m",
              "n""o""p""q""r""s""t""u""v""w""x""y""z"};
 
         int justifiedIndex = ++;
 
         if(justifiedIndex >= easyNames.length)
             return "local" + (justifiedIndex - easyNames.length);
         else
             return easyNames[justifiedIndex];
     }
 
     void setClassNameToAbbreviation(Map map)
     {
          = map;
     }
 
     Local getLocalForStackOp(JimpleBody listBodyTypeStack typeStack,
         int index)
     {
         if(typeStack.get(index).equals(Double2ndHalfType.v()) ||
             typeStack.get(index).equals(Long2ndHalfType.v()))
         {
             index--;
         }
 
         return getLocalCreatingIfNecessary(listBody"$stack" + index, UnknownType.v());
     }
 
     {
         StringBuffer buffer = new StringBuffer(new Character(className.charAt(0)).toString());
         int periodIndex = 0;
 
         for(;;)
         {
             periodIndex = className.indexOf('.'periodIndex + 1);
 
             if(periodIndex == -1)
                 break;
 
             buffer.append(Character.toLowerCase(className.charAt(periodIndex + 1)));
         }
 
         return buffer.toString();
     }
 
     String getNormalizedClassName(String className)
     {
         className = className.replace('/''.');
 
         if(className.endsWith(";"))
             className = className.substring(0, className.length() - 1);
 
         // Handle array case
         {
             int numDimensions = 0;
 
             while(className.startsWith("["))
             {
                 numDimensions++;
                 className = className.substring(1, className.length());
                 className = className + "[]";
             }
 
             if(numDimensions != 0)
             {
                 if(!className.startsWith("L"))
                     throw new RuntimeException("For some reason an array reference does not start with L");
 
                 className = className.substring(1, className.length());
             }
         }
 
 
         return className;
     }
 
     public Local getLocal(Body bString name
         throws soot.jimple.NoSuchLocalException
     {
         Iterator localIt = b.getLocals().iterator();
 
         while(localIt.hasNext())
         {
             Local local = (LocallocalIt.next();
 
             if(local.getName().equals(name))
                 return local;
         }
 
         throw new soot.jimple.NoSuchLocalException();
     }
 
 
     public boolean declaresLocal(Body bString localName)
     {
         Iterator localIt = b.getLocals().iterator();
 
         while(localIt.hasNext())
         {
             Local local = (LocallocalIt.next();
 
             if(local.getName().equals(localName))
                 return true;
         }
 
         return false;
     }
 
      Local
         getLocalCreatingIfNecessary(JimpleBody listBodyString nameType type)
     {
         if(declaresLocal(listBodyname))
         {
             return getLocal(listBodyname);
         }
         else {
             Local l = Jimple.v().newLocal(nametype);
             listBody.getLocals().add(l);
 
             return l;
         }
     }
 
     Local getLocalForIndex(JimpleBody listBodyint index)
     {
         String name = null;
         String debug_type = null;
         boolean assignedName = false;
         if( &&  != null)
         {
             if( != -1)
             {
 
 	      // Feng asks: why this is necessary? it does wrong thing
 	      //            for searching local variable names.
 	      // It is going to be verified with plam.
                 if()
                     ++;
                 if()
                     ++;
 
                 name = .getLocalVariableName(index);
                 if ( != null){
                debug_type = .getLocalVariableType(index);
                if (debug_type != null){
                }
                 }
                 if(name != null
                     assignedName = true;
             }
         }  
         
         if(!assignedName)
             name = "l" + index;
 
         if(declaresLocal(listBodyname))
             return getLocal(listBodyname);
         else {
             Local l = Jimple.v().newLocal(name,
                 UnknownType.v());
 
             listBody.getLocals().add(l);
             /*if (debug_type != null){
                 l.addTag(new DebugTypeTag(debug_type));
             } */   
 
             return l;
         }
     }
 
     /*
     void setLocalType(Local local, List locals,
         int localIndex, Type type)
     {
         if(local.getType().equals(UnknownType.v()) ||
             local.getType().equals(type))
         {
             local.setType(type);
 
             if(local.getType().equals(DoubleType.v()) ||
                 local.getType().equals(LongType.v()))
             {
                 // This means the next local becomes voided, since these types occupy two
                 // words.
 
                 Local secondHalf = (Local) locals.get(localIndex + 1);
 
                 secondHalf.setType(VoidType.v());
             }
 
             return;
         }
 
         if(type.equals(IntType.v()))
         {
             if(local.getType().equals(BooleanType.v()) ||
                local.getType().equals(CharType.v()) ||
                local.getType().equals(ShortType.v()) ||
                local.getType().equals(ByteType.v()))
             {
                 // Even though it's not the same, it's ok, because booleans, chars, shorts, and
                 // bytes are all sort of treated like integers by the JVM.
                 return;
             }
 
         }
 
         throw new RuntimeException("required and actual types do not match: " + type.toString() +
                 " with " + local.getType().toString());
     }    */

    
Verifies the prospective name for validity as a Jimple name. In particular, first-char is alpha | _ | $, subsequent-chars are alphanum | _ | $. We could use isJavaIdentifier, except that Jimple's grammar doesn't support all of those, just ASCII. I'd put this in soot.Local, but that's an interface.

Author(s):
Patrick Lam
 
     boolean isValidJimpleName(String prospectiveName) {
         if(prospectiveName == nullreturn false;
 	for (int i = 0; i < prospectiveName.length(); i++) {
 	    char c = prospectiveName.charAt(i);
 	    if (i == 0 && c >= '0' && c <= '9')
 		return false;
 
 	    if (!((c >= '0' && c <= '9') ||
 		  (c >= 'a' && c <= 'z') ||
 		  (c >= 'A' && c <= 'Z') ||
 		  (c == '_' || c == '$')))
 		return false;
 	}
 	return true;
     }
 
     private void addAnnotationVisibilityAttribute(Host hostattribute_info attributeClassFile coffiClassList references){
         VisibilityAnnotationTag tag;
         if (attribute instanceof RuntimeVisibleAnnotations_attribute){
             tag = new VisibilityAnnotationTag(.);         
             RuntimeVisibleAnnotations_attribute attr = (RuntimeVisibleAnnotations_attribute)attribute;
             addAnnotations(attr.number_of_annotationsattr.annotationscoffiClasstagreferences);
         }
         else {
             tag = new VisibilityAnnotationTag(.);
             addAnnotations(attr.number_of_annotationsattr.annotationscoffiClasstagreferences);
         }
         host.addTag(tag); 
     }
     
     private void addAnnotationVisibilityParameterAttribute(Host hostattribute_info attributeClassFile coffiClassList references){
         VisibilityParameterAnnotationTag tag;
         if (attribute instanceof RuntimeVisibleParameterAnnotations_attribute){
             tag = new VisibilityParameterAnnotationTag(attr.num_parameters.);
             for (int i = 0; i < attr.num_parametersi++){
                 parameter_annotation pAnnot = attr.parameter_annotations[i];
                 addAnnotations(pAnnot.num_annotationspAnnot.annotationscoffiClassvTagreferences);
                 tag.addVisibilityAnnotation(vTag);
             }
         }
         else {
             tag = new VisibilityParameterAnnotationTag(attr.num_parameters.);
             for (int i = 0; i < attr.num_parametersi++){
                 parameter_annotation pAnnot = attr.parameter_annotations[i];
                 addAnnotations(pAnnot.num_annotationspAnnot.annotationscoffiClassvTagreferences);
                 tag.addVisibilityAnnotation(vTag);
             }
         }
         host.addTag(tag); 
     }
 
     private void addAnnotations(int numAnnotsannotation [] annotationsClassFile coffiClassVisibilityAnnotationTag tagList references){
         for (int i = 0; i < numAnnotsi++){
             annotation annot = annotations[i];
             String annotType = ((CONSTANT_Utf8_info)coffiClass.constant_pool[annot.type_index]).convert();
             String ref = annotType.substring(1, annotType.length()-1);
             ref = ref.replace('/''.');
             references.add(ref);
             int numElems = annot.num_element_value_pairs;
             AnnotationTag annotTag = new AnnotationTag(annotTypenumElems);
             annotTag.setElems(createElementTags(numElemscoffiClassannot.element_value_pairs));
             tag.addAnnotation(annotTag);
         }
     }
     
     private ArrayList<AnnotationElemcreateElementTags(int countClassFile coffiClasselement_value [] elems){
        ArrayList<AnnotationElemlist = new ArrayList<AnnotationElem>();
        for (int j = 0; j < countj++){
            element_value ev = elems[j];
            char kind = ev.tag;
            String elemName = "default";
            if (ev.name_index != 0){
                elemName = ((CONSTANT_Utf8_info)coffiClass.constant_pool[ev.name_index]).convert();
            }
            if (kind == 'B' || kind == 'C' || kind == 'I' || kind == 'S' || kind == 'Z' || kind == 'D' || kind == 'F' || kind == 'J' || kind == 's'){
                constant_element_value cev = (constant_element_value)ev;
                if (kind == 'B' || kind == 'C' || kind == 'I' || kind == 'S' || kind == 'Z'){
                    cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
                    int constant_val = (int)((CONSTANT_Integer_info)cval).;
                    AnnotationIntElem elem = new AnnotationIntElem(constant_valkindelemName);
                    list.add(elem);
                }
                else if (kind == 'D'){
                    cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
                    double constant_val = ((CONSTANT_Double_info)cval).convert();
                    AnnotationDoubleElem elem = new AnnotationDoubleElem(constant_valkindelemName);
                    list.add(elem);
                
                }
                else if (kind == 'F'){
                    cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
                    float constant_val = ((CONSTANT_Float_info)cval).convert();
                    AnnotationFloatElem elem = new AnnotationFloatElem(constant_valkindelemName);
                    list.add(elem);
                
                }
                else if (kind == 'J'){
                    cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
                    CONSTANT_Long_info lcval = (CONSTANT_Long_info)cval;
                    long constant_val = (lcval.high << 32) + lcval.low;
                    AnnotationLongElem elem = new AnnotationLongElem(constant_valkindelemName);
                    list.add(elem);
                
                }
                else if (kind == 's'){
                    cp_info cval = coffiClass.constant_pool[cev.constant_value_index];
                    String constant_val = ((CONSTANT_Utf8_info)cval).convert();
                    AnnotationStringElem elem = new AnnotationStringElem(constant_valkindelemName);
                    list.add(elem);
                }
            }
            else if (kind == 'e'){
                enum_constant_element_value ecev = (enum_constant_element_value)ev;
                cp_info type_val = coffiClass.constant_pool[ecev.type_name_index];
                String type_name = ((CONSTANT_Utf8_info)type_val).convert();
                cp_info name_val = coffiClass.constant_pool[ecev.constant_name_index];
                String constant_name = ((CONSTANT_Utf8_info)name_val).convert();
                AnnotationEnumElem elem = new AnnotationEnumElem(type_nameconstant_namekindelemName);
                list.add(elem);
            }
            else if (kind == 'c'){
                class_element_value cev = (class_element_value)ev;
                cp_info cval = coffiClass.constant_pool[cev.class_info_index];
                CONSTANT_Utf8_info sval = (CONSTANT_Utf8_info)cval;
                String desc = sval.convert();
                
                AnnotationClassElem elem = new AnnotationClassElem(desckindelemName);
                list.add(elem);
            }
            else if (kind == '['){
                array_element_value aev = (array_element_value)ev;
                int num_vals = aev.num_values;
                ArrayList<AnnotationElemelemVals = createElementTags(num_valscoffiClassaev.values);
                AnnotationArrayElem elem = new AnnotationArrayElem(elemValskindelemName);
                list.add(elem);
            }
            else if (kind == '@'){
                annotation_element_value aev = (annotation_element_value)ev;