changes: now, the annotated SSJava class library passes the flow-down rule checking.
authoryeom <yeom>
Fri, 29 Apr 2011 23:42:00 +0000 (23:42 +0000)
committeryeom <yeom>
Fri, 29 Apr 2011 23:42:00 +0000 (23:42 +0000)
Robust/src/Analysis/SSJava/CompositeLocation.java
Robust/src/Analysis/SSJava/FlowDownCheck.java
Robust/src/Analysis/SSJava/NTuple.java
Robust/src/ClassLibrary/SSJava/Object.java
Robust/src/ClassLibrary/SSJava/String.java

index 15af1f82e827987941e26210eef8f775283d09d6..1adb4d4c0842fb36f8522f750436e57253747d8a 100644 (file)
@@ -30,14 +30,13 @@ public class CompositeLocation extends Location {
     if (loc instanceof DeltaLocation) {
       type = Location.DELTA;
     }
-
     locTuple.addElement(loc);
 
   }
 
   public void addLocationSet(Set<Location> set) {
 
-    for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
+    for (Iterator iterator = set.iterator(); iterator.hasNext();) {
       Location location = (Location) iterator.next();
       locTuple.addElement(location);
     }
@@ -48,7 +47,7 @@ public class CompositeLocation extends Location {
 
     // need to get more optimization version later
     Set<Location> locSet = getBaseLocationSet();
-    for (Iterator iterator = locSet.iterator(); iterator.hasNext(); ) {
+    for (Iterator iterator = locSet.iterator(); iterator.hasNext();) {
       Location location = (Location) iterator.next();
       if (location.getClassDescriptor().equals(cd)) {
         return location;
@@ -64,7 +63,7 @@ public class CompositeLocation extends Location {
     Map<ClassDescriptor, Location> cd2loc = new Hashtable<ClassDescriptor, Location>();
 
     Set<Location> baseLocSet = getBaseLocationSet();
-    for (Iterator iterator = baseLocSet.iterator(); iterator.hasNext(); ) {
+    for (Iterator iterator = baseLocSet.iterator(); iterator.hasNext();) {
       Location location = (Location) iterator.next();
       cd2loc.put(location.getClassDescriptor(), location);
     }
@@ -138,6 +137,15 @@ public class CompositeLocation extends Location {
     return result;
   }
 
+  public void removieLocation(ClassDescriptor cd) {
+    for (int i = 0; i < locTuple.size(); i++) {
+      if (locTuple.at(i).getClassDescriptor().equals(cd)) {
+        locTuple.removeAt(i);
+        return;
+      }
+    }
+  }
+
   public String toString() {
 
     // for better representation
index e44722291cec1ec6d1b873956f185ab92bf9de85..3828e88505ca8d19a7b22eab18d3db2f5f6c2373 100644 (file)
@@ -24,6 +24,7 @@ import IR.Tree.AssignmentNode;
 import IR.Tree.BlockExpressionNode;
 import IR.Tree.BlockNode;
 import IR.Tree.BlockStatementNode;
+import IR.Tree.CastNode;
 import IR.Tree.CreateObjectNode;
 import IR.Tree.DeclarationNode;
 import IR.Tree.ExpressionNode;
@@ -35,6 +36,7 @@ import IR.Tree.LoopNode;
 import IR.Tree.MethodInvokeNode;
 import IR.Tree.NameNode;
 import IR.Tree.OpNode;
+import IR.Tree.ReturnNode;
 import IR.Tree.SubBlockNode;
 import IR.Tree.TertiaryNode;
 import IR.Tree.TreeNode;
@@ -86,7 +88,7 @@ public class FlowDownCheck {
       ClassDescriptor cd = (ClassDescriptor) obj;
       toanalyze.remove(cd);
 
-      if(!cd.isInterface()){
+      if (!cd.isInterface()) {
         checkDeclarationInClass(cd);
         for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
           MethodDescriptor md = (MethodDescriptor) method_it.next();
@@ -141,7 +143,7 @@ public class FlowDownCheck {
       Object obj = toanalyze.iterator().next();
       ClassDescriptor cd = (ClassDescriptor) obj;
       toanalyze.remove(cd);
-      
+
       checkClass(cd);
       for (Iterator method_it = cd.getMethods(); method_it.hasNext();) {
         MethodDescriptor md = (MethodDescriptor) method_it.next();
@@ -219,6 +221,8 @@ public class FlowDownCheck {
 
   private CompositeLocation checkLocationFromBlockNode(MethodDescriptor md, SymbolTable nametable,
       BlockNode bn) {
+
+    bn.getVarTable().setParent(nametable);
     // it will return the lowest location in the block node
     CompositeLocation lowestLoc = null;
     for (int i = 0; i < bn.size(); i++) {
@@ -258,8 +262,8 @@ public class FlowDownCheck {
       break;
 
     case Kind.ReturnNode:
-      // checkLocationFromReturnNode(md, nametable, (ReturnNode) bsn);
-      return null;
+      compLoc = checkLocationFromReturnNode(md, nametable, (ReturnNode) bsn);
+      break;
 
     case Kind.SubBlockNode:
       compLoc = checkLocationFromSubBlockNode(md, nametable, (SubBlockNode) bsn);
@@ -273,6 +277,23 @@ public class FlowDownCheck {
     return compLoc;
   }
 
+  private CompositeLocation checkLocationFromReturnNode(MethodDescriptor md, SymbolTable nametable,
+      ReturnNode rn) {
+    ClassDescriptor cd = md.getClassDesc();
+    CompositeLocation loc = new CompositeLocation(cd);
+    // TODO: by default, return node has "bottom" location no matter what it is
+    // going to return
+    // but definitely I need to consider it more!!!
+    loc.addLocation(Location.createBottomLocation(cd));
+    /*
+     * ExpressionNode returnExp = rn.getReturnExpression(); if
+     * (rn.getReturnExpression() != null) { loc =
+     * checkLocationFromExpressionNode(md, nametable, returnExp, loc); }
+     */
+    // System.out.println(rn.printNode(0) + "  has loc=" + loc);
+    return loc;
+  }
+
   private CompositeLocation checkLocationFromLoopNode(MethodDescriptor md, SymbolTable nametable,
       LoopNode ln) {
 
@@ -298,6 +319,7 @@ public class FlowDownCheck {
     } else {
       // check for loop case
       BlockNode bn = ln.getInitializer();
+      bn.getVarTable().setParent(nametable);
 
       // calculate glb location of condition and update statements
       CompositeLocation condLoc =
@@ -313,6 +335,8 @@ public class FlowDownCheck {
       glbInputSet.add(updateLoc);
 
       CompositeLocation glbLocOfForLoopCond = CompositeLattice.calculateGLB(cd, glbInputSet, cd);
+
+      // check location of 'forloop' body
       CompositeLocation blockLoc = checkLocationFromBlockNode(md, bn.getVarTable(), ln.getBody());
 
       if (blockLoc == null) {
@@ -398,20 +422,29 @@ public class FlowDownCheck {
         // checking location order
         if (!CompositeLattice.isGreaterThan(expressionLoc, destLoc, localCD)) {
           throw new Error("The value flow from " + expressionLoc + " to " + destLoc
-              + " does not respect location hierarchy on the assignment " + dn.printNode(0));
+              + " does not respect location hierarchy on the assignment " + dn.printNode(0)
+              + " at " + md.getClassDesc().getSourceFileName() + "::" + dn.getNumLine());
         }
       }
       return expressionLoc;
 
     } else {
-      return null;
+
+      if (destLoc instanceof Location) {
+        CompositeLocation comp = new CompositeLocation(localCD);
+        comp.addLocation(destLoc);
+        return comp;
+      } else {
+        return (CompositeLocation) destLoc;
+      }
+
     }
 
   }
 
   private void checkDeclarationInSubBlockNode(MethodDescriptor md, SymbolTable nametable,
       SubBlockNode sbn) {
-    checkDeclarationInBlockNode(md, nametable, sbn.getBlockNode());
+    checkDeclarationInBlockNode(md, nametable.getParent(), sbn.getBlockNode());
   }
 
   private CompositeLocation checkLocationFromBlockExpressionNode(MethodDescriptor md,
@@ -464,6 +497,10 @@ public class FlowDownCheck {
       compLoc = checkLocationFromTertiaryNode(md, nametable, (TertiaryNode) en);
       break;
 
+    case Kind.CastNode:
+      compLoc = checkLocationFromCastNode(md, nametable, (CastNode) en);
+      break;
+
     // case Kind.InstanceOfNode:
     // checkInstanceOfNode(md, nametable, (InstanceOfNode) en, td);
     // return null;
@@ -491,6 +528,15 @@ public class FlowDownCheck {
 
   }
 
+  private CompositeLocation checkLocationFromCastNode(MethodDescriptor md, SymbolTable nametable,
+      CastNode cn) {
+
+    ExpressionNode en = cn.getExpression();
+    return checkLocationFromExpressionNode(md, nametable, en,
+        new CompositeLocation(md.getClassDesc()));
+
+  }
+
   private CompositeLocation checkLocationFromTertiaryNode(MethodDescriptor md,
       SymbolTable nametable, TertiaryNode tn) {
     ClassDescriptor cd = md.getClassDesc();
@@ -614,7 +660,6 @@ public class FlowDownCheck {
             cd));
     addTypeLocation(aan.getExpression().getType(), arrayLoc);
     glbInputSet.add(arrayLoc);
-
     CompositeLocation indexLoc =
         checkLocationFromExpressionNode(md, nametable, aan.getIndex(), new CompositeLocation(cd));
     glbInputSet.add(indexLoc);
@@ -669,9 +714,11 @@ public class FlowDownCheck {
       addTypeLocation(on.getRight().getType(), rightLoc);
     }
 
-    System.out.println("checking op node=" + on.printNode(0));
-    System.out.println("left loc=" + leftLoc + " from " + on.getLeft().getClass());
-    System.out.println("right loc=" + rightLoc);
+    // System.out.println("checking op node=" + on.printNode(0));
+    // System.out.println("left loc=" + leftLoc + " from " +
+    // on.getLeft().getClass());
+    // System.out.println("right loc=" + rightLoc + " from " +
+    // on.getLeft().getClass());
 
     Operation op = on.getOp();
 
@@ -681,8 +728,7 @@ public class FlowDownCheck {
     case Operation.UNARYMINUS:
     case Operation.LOGIC_NOT:
       // single operand
-      on.setType(new TypeDescriptor(TypeDescriptor.BOOLEAN));
-      break;
+      return leftLoc;
 
     case Operation.LOGIC_OR:
     case Operation.LOGIC_AND:
@@ -716,8 +762,6 @@ public class FlowDownCheck {
       throw new Error(op.toString());
     }
 
-    return null;
-
   }
 
   private CompositeLocation checkLocationFromLiteralNode(MethodDescriptor md,
@@ -741,6 +785,11 @@ public class FlowDownCheck {
     } else {
 
       String varname = nd.toString();
+      if (varname.equals("this")) {
+        // 'this' itself is top location in the local hierarchy
+        loc.addLocation(Location.createTopLocation(md.getClassDesc()));
+        return loc;
+      }
       Descriptor d = (Descriptor) nametable.get(varname);
 
       Location localLoc = null;
@@ -766,14 +815,23 @@ public class FlowDownCheck {
   private CompositeLocation checkLocationFromFieldAccessNode(MethodDescriptor md,
       SymbolTable nametable, FieldAccessNode fan, CompositeLocation loc) {
 
-    FieldDescriptor fd = fan.getField();
-    Location fieldLoc = td2loc.get(fd);
-    loc.addLocation(fieldLoc);
-
     ExpressionNode left = fan.getExpression();
-    CompositeLocation compLoc = checkLocationFromExpressionNode(md, nametable, left, loc);
-    addTypeLocation(left.getType(), compLoc);
-    return compLoc;
+    loc = checkLocationFromExpressionNode(md, nametable, left, loc);
+    addTypeLocation(left.getType(), loc);
+
+    if (!left.getType().isPrimitive()) {
+      FieldDescriptor fd = fan.getField();
+      Location fieldLoc = td2loc.get(fd);
+
+      // in the case of "this.field", need to get rid of 'this' location from
+      // the composite location
+      if (loc.getCd2Loc().containsKey(md.getClassDesc())) {
+        loc.removieLocation(md.getClassDesc());
+      }
+      loc.addLocation(fieldLoc);
+    }
+
+    return loc;
   }
 
   private CompositeLocation checkLocationFromAssignmentNode(MethodDescriptor md,
@@ -793,10 +851,13 @@ public class FlowDownCheck {
     if (!postinc) {
       srcLocation = new CompositeLocation(cd);
       srcLocation = checkLocationFromExpressionNode(md, nametable, an.getSrc(), srcLocation);
-
+      // System.out.println("an=" + an.printNode(0) + " an.getSrc()=" +
+      // an.getSrc().getClass()
+      // + " at " + cd.getSourceFileName() + "::" + an.getNumLine());
       if (!CompositeLattice.isGreaterThan(srcLocation, destLocation, cd)) {
         throw new Error("The value flow from " + srcLocation + " to " + destLocation
-            + " does not respect location hierarchy on the assignment " + an.printNode(0));
+            + " does not respect location hierarchy on the assignment " + an.printNode(0) + "at "
+            + cd.getSourceFileName() + "::" + an.getNumLine());
       }
     } else {
       destLocation =
@@ -849,7 +910,7 @@ public class FlowDownCheck {
         Location loc = new Location(cd, locationID);
         td2loc.put(vd, loc);
         addTypeLocation(vd.getType(), loc);
-        
+
       } else if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
 
         CompositeLocation compLoc = new CompositeLocation(cd);
@@ -937,7 +998,7 @@ public class FlowDownCheck {
 
     Vector<AnnotationDescriptor> annotationVec = fd.getType().getAnnotationMarkers();
 
-    // currently enforce every variable to have corresponding location
+    // currently enforce every field to have corresponding location
     if (annotationVec.size() == 0) {
       throw new Error("Location is not assigned to the field " + fd.getSymbol() + " of the class "
           + cd.getSymbol());
@@ -949,23 +1010,23 @@ public class FlowDownCheck {
           + " has more than one location.");
     }
 
-    // check if location is defined
     AnnotationDescriptor ad = annotationVec.elementAt(0);
-    if (ad.getType() == AnnotationDescriptor.MARKER_ANNOTATION) {
-      String locationID = annotationVec.elementAt(0).getMarker();
-      Lattice<String> lattice = (Lattice<String>) state.getCd2LocationOrder().get(cd);
 
-      if (lattice == null || (!lattice.containsKey(locationID))) {
-        throw new Error("Location " + locationID
-            + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
-      }
+    if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) {
 
-      Location localLoc = new Location(cd, locationID);
-      td2loc.put(fd, localLoc);
-      addTypeLocation(fd.getType(), localLoc);
+      if (ad.getMarker().equals(SSJavaAnalysis.LOC)) {
+        String locationID = ad.getValue();
+        // check if location is defined
+        Lattice<String> lattice = (Lattice<String>) state.getCd2LocationOrder().get(cd);
+        if (lattice == null || (!lattice.containsKey(locationID))) {
+          throw new Error("Location " + locationID
+              + " is not defined in the location hierarchy of class " + cd.getSymbol() + ".");
+        }
+        Location loc = new Location(cd, locationID);
+        td2loc.put(fd, loc);
+        addTypeLocation(fd.getType(), loc);
 
-    } else if (ad.getType() == AnnotationDescriptor.SINGLE_ANNOTATION) {
-      if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
+      } else if (ad.getMarker().equals(SSJavaAnalysis.DELTA)) {
 
         if (ad.getValue().length() == 0) {
           throw new Error("Delta function of " + fd.getSymbol() + " does not have any locations: "
@@ -995,6 +1056,7 @@ public class FlowDownCheck {
       }
     }
 
+   
   }
 
   private void addTypeLocation(TypeDescriptor type, Location loc) {
@@ -1007,7 +1069,7 @@ public class FlowDownCheck {
 
     public static boolean isGreaterThan(Location loc1, Location loc2, ClassDescriptor priorityCD) {
 
-      // System.out.println("isGreaterThan=" + loc1 + " ? " + loc2);
+      // System.out.println("\nisGreaterThan=" + loc1 + " ? " + loc2);
       CompositeLocation compLoc1;
       CompositeLocation compLoc2;
 
index c6a1168d50f6dcc89bbe3f40ce8c004fb6f9538c..d001e6fb3a8b2d2c11de882c46c7352da21bded8 100644 (file)
@@ -57,5 +57,9 @@ public class NTuple<T> {
   public int hashCode() {
     return elements.hashCode();
   }
+  
+  public void removeAt(int i){
+    elements.remove(i);
+  }
 
 }
index df78349dc3ed5f5813ce6b5a5d1a8af1a28b5eb5..7df288910013d1dd14017508a4325f0ab794513b 100644 (file)
@@ -1,7 +1,7 @@
 public class Object {
   
   locdef{  
-    data
+    in
   }
   
   public native int hashCode();
@@ -14,7 +14,7 @@ public class Object {
     return "Object"+hashCode();
   }
 
-  public boolean equals(@LOC("data") Object o) {
+  public boolean equals(@LOC("in") Object o) {
     if (o==this)
       return true;
     return false;
index 24a87cf03f4c0df694b89cae3fe6f4630187680c..43a71a2fa8a04d627ade7b7184145044a9bc095e 100644 (file)
@@ -1,76 +1,97 @@
 public class String {
-  char value[];
-  int count;
-  int offset;
-  private int cachedHashcode;
+
+  locdef{
+    data<proc,proc<c,c<in,in*,c*,proc*,data*
+  }
+
+  @LOC("data") char value[];
+  @LOC("data") int count;
+  @LOC("data") int offset;
+  @LOC("data") private int cachedHashcode;
 
   private String() {
   }
 
-  public String(char c) {
-    char[] str = new char[1];
+  public String(@LOC("in") char c) {
+    @LOC("data") char[] str = new char[1];
     str[0] = c;
     String(str);
   }
 
-  public String(char str[]) {
-    char charstr[]=new char[str.length];
-    for(int i=0; i<str.length; i++)
+  public String(@LOC("in") char str[]) {
+    @LOC("in") char charstr[]=new char[str.length];
+    for(@LOC("c") int i=0; i<str.length; i++)
       charstr[i]=str[i];
     this.value=charstr;
     this.count=str.length;
     this.offset=0;
   }
 
-  public String(byte str[]) {
-    char charstr[]=new char[str.length];
-    for(int i=0; i<str.length; i++)
+  public String(@LOC("in") byte str[]) {
+    @LOC("in") char charstr[]=new char[str.length];
+    for(@LOC("c") int i=0; i<str.length; i++)
       charstr[i]=(char)str[i];
     this.value=charstr;
     this.count=str.length;
     this.offset=0;
   }
 
-  public String(byte str[], int offset, int length) {
+  public String(@LOC("in") byte str[], @LOC("in") int offset, @LOC("in") int length) {
     if (length>(str.length-offset))
       length=str.length-offset;
-    char charstr[]=new char[length];
-    for(int i=0; i<length; i++)
+    @LOC("in") char charstr[]=new char[length];
+    for(@LOC("c")int i=0; i<length; i++)
       charstr[i]=(char)str[i+offset];
     this.value=charstr;
     this.count=length;
     this.offset=0;
   }
-  
-  public String(byte str[], String encoding) {
-    int length = this.count;
+
+  public String(@LOC("in") byte str[], @LOC("in") String encoding) {
+    @LOC("data") int length = this.count;
     if (length>(str.length))
       length=str.length;
-    char charstr[]=new char[length];
-    for(int i=0; i<length; i++)
+    @LOC("data") char charstr[]=new char[length];
+    for(@LOC("c") int i=0; i<length; i++)
       charstr[i]=(char)str[i];
     this.value=charstr;
     this.count=length;
     this.offset=0;
   }
-  
-  public String(char str[], int offset, int length) {
+
+  public String(@LOC("in") char str[], @LOC("in") int offset, @LOC("in") int length) {
     if (length>(str.length-offset))
       length=str.length-offset;
-    char charstr[]=new char[length];
-    for(int i=0; i<length; i++)
+    @LOC("in") char charstr[]=new char[length];
+    for(@LOC("c") int i=0; i<length; i++)
       charstr[i]=str[i+offset];
     this.value=charstr;
     this.count=length;
     this.offset=0;
   }
 
-  public String(String str) {
+  public String(@LOC("in") String str) {
     this.value=str.value;
     this.count=str.count;
     this.offset=str.offset;
   }
-/*
+  
+  public String concat(@LOC("in") String str) {
+    @LOC("data") String newstr=new String();
+    newstr.count=this.count+str.count;
+    @LOC("data") char charstr[]=new char[newstr.count];
+    newstr.value=charstr;
+    newstr.offset=0;
+    for(@LOC("c") int i=0; i<count; i++) {
+      charstr[i]=value[i+offset];
+    }
+    for(@LOC("c") int i=0; i<str.count; i++) {
+      charstr[i+count]=str.value[i+str.offset];
+    }
+    return newstr;
+  }
+  
+  /*
   public String(StringBuffer strbuf) {
     value=new char[strbuf.length()];
     count=strbuf.length();
@@ -78,21 +99,23 @@ public class String {
     for(int i=0; i<count; i++)
       value[i]=strbuf.value[i];
   }
-*/
-  public boolean endsWith(String suffix) {
+   */
+  
+  /*
+  public boolean endsWith(@LOC("in") String suffix) {
     return regionMatches(count - suffix.count, suffix, 0, suffix.count);
   }
 
 
-  public String substring(int beginIndex) {
+  public String substring(@LOC("in") int beginIndex) {
     return substring(beginIndex, this.count);
   }
 
-  public String subString(int beginIndex, int endIndex) {
+  public String subString(@LOC("in") int beginIndex, @LOC("in") int endIndex) {
     return substring(beginIndex, endIndex);
   }
 
-  public String substring(int beginIndex, int endIndex) {
+  public String substring(@LOC("in") int beginIndex, @LOC("in") int endIndex) {
     String str=new String();
     if (beginIndex>this.count||endIndex>this.count||beginIndex>endIndex) {
       // FIXME
@@ -104,53 +127,38 @@ public class String {
     return str;
   }
 
-  public String subString(int beginIndex) {
+  public String subString(@LOC("in") int beginIndex) {
     return this.subString(beginIndex, this.count);
   }
 
-  public int lastindexOf(int ch) {
+  public int lastindexOf(@LOC("in") int ch) {
     return this.lastindexOf(ch, count - 1);
   }
 
-  public int lastIndexOf(char ch) {
+  public int lastIndexOf(@LOC("in") char ch) {
     return this.lastindexOf((int)ch, count - 1);
   }
-  
-  public static String concat2(String s1, String s2) {
+
+  public static String concat2(@LOC("in") String s1, @LOC("in") String s2) {
     if (s1==null)
       return "null".concat(s2);
     else
       return s1.concat(s2);
   }
 
-  public String concat(String str) {
-    String newstr=new String();
-    newstr.count=this.count+str.count;
-    char charstr[]=new char[newstr.count];
-    newstr.value=charstr;
-    newstr.offset=0;
-    for(int i=0; i<count; i++) {
-      charstr[i]=value[i+offset];
-    }
-    for(int i=0; i<str.count; i++) {
-      charstr[i+count]=str.value[i+str.offset];
-    }
-    return newstr;
-  }
-
-  public int lastindexOf(int ch, int fromIndex) {
+  public int lastindexOf(@LOC("in") int ch, @LOC("in") int fromIndex) {
     for(int i=fromIndex; i>0; i--)
       if (this.charAt(i)==ch)
-       return i;
+        return i;
     return -1;
   }
 
-  public String replace(char oldch, char newch) {
+  public String replace(@LOC("in") char oldch, @LOC("in") char newch) {
     char[] buffer=new char[count];
     for(int i=0; i<count; i++) {
       char x=charAt(i);
       if (x==oldch)
-       x=newch;
+        x=newch;
       buffer[i]=x;
     }
     return new String(buffer);
@@ -161,7 +169,7 @@ public class String {
     for(int i=0; i<count; i++) {
       char x=charAt(i);
       if (x>='a'&&x<='z') {
-       x=(char) ((x-'a')+'A');
+        x=(char) ((x-'a')+'A');
       }
       buffer[i]=x;
     }
@@ -173,78 +181,78 @@ public class String {
     for(int i=0; i<count; i++) {
       char x=charAt(i);
       if (x>='A'&&x<='Z') {
-       x=(char) ((x-'A')+'a');
+        x=(char) ((x-'A')+'a');
       }
       buffer[i]=x;
     }
     return new String(buffer);
   }
 
-  public int indexOf(int ch) {
+  public int indexOf(@LOC("in") int ch) {
     return this.indexOf(ch, 0);
   }
 
-  public int indexOf(int ch, int fromIndex) {
+  public int indexOf(@LOC("in") int ch, @LOC("in") int fromIndex) {
     for(int i=fromIndex; i<count; i++)
       if (this.charAt(i)==ch)
-       return i;
+        return i;
     return -1;
   }
 
-  public int indexOf(String str) {
+  public int indexOf(@LOC("in") String str) {
     return this.indexOf(str, 0);
   }
 
-  public int indexOf(String str, int fromIndex) {
+  public int indexOf(@LOC("in") String str, @LOC("in") int fromIndex) {
     if (fromIndex<0)
       fromIndex=0;
     for(int i=fromIndex; i<=(count-str.count); i++)
       if (regionMatches(i, str, 0, str.count))
-       return i;
+        return i;
     return -1;
   }
 
-       public int indexOfIgnoreCase(String str, int fromIndex) {
-               if (fromIndex < 0) 
-                       fromIndex = 0;
-       }
+  public int indexOfIgnoreCase(@LOC("in") String str, @LOC("in") int fromIndex) {
+    if (fromIndex < 0) 
+      fromIndex = 0;
+  }
 
-  public int lastIndexOf(String str, int fromIndex) {
+  public int lastIndexOf(@LOC("in") String str, @LOC("in") int fromIndex) {
     int k=count-str.count;
     if (k>fromIndex)
       k=fromIndex;
     for(; k>=0; k--) {
       if (regionMatches(k, str, 0, str.count))
-       return k;
+        return k;
     }
     return -1;
   }
 
-  public int lastIndexOf(String str) {
+  public int lastIndexOf(@LOC("in") String str) {
     return lastIndexOf(str, count-str.count);
   }
 
-  public boolean startsWith(String str) {
+  public boolean startsWith(@LOC("in") String str) {
     return regionMatches(0, str, 0, str.count);
   }
 
-  public boolean startsWith(String str, int toffset) {
+  public boolean startsWith(@LOC("in") String str, @LOC("in") int toffset) {
     return regionMatches(toffset, str, 0, str.count);
   }
 
-  public boolean regionMatches(int toffset, String other, int ooffset, int len) {
+  public boolean regionMatches(@LOC("in") int toffset, @LOC("in") String other, @LOC("in") int ooffset, @LOC("in") int len) {
     if (toffset<0 || ooffset <0 || (toffset+len)>count || (ooffset+len)>other.count)
       return false;
     for(int i=0; i<len; i++)
       if (other.value[i+other.offset+ooffset]!=
-          this.value[i+this.offset+toffset])
-       return false;
+        this.value[i+this.offset+toffset])
+        return false;
     return true;
   }
 
   public char[] toCharArray() {
-    char str[]=new char[count];
-    for(int i=0; i<count; i++)
+    @LOC("data") char str[]=new char[count];
+    for(@LOC("data") int i=0; i<count; i++)
       str[i]=value[i+offset];
     return str;
   }
@@ -255,12 +263,12 @@ public class String {
       str[i]=(byte)value[i+offset];
     return str;
   }
-  
-  public void getChars(char dst[], int dstBegin) {
+
+  public void getChars(@LOC("in") char dst[], @LOC("in") int dstBegin) {
     getChars(0, count, dst, dstBegin);
   }
-  
-  public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
+
+  public void getChars(@LOC("in") int srcBegin, @LOC("in") int srcEnd, @LOC("in") char dst[],@LOC("in")  int dstBegin) {
     if((srcBegin < 0) || (srcEnd > count) || (srcBegin > srcEnd)) {
       // FIXME
       System.printString("Index error: "+srcBegin+" "+srcEnd+" "+count+"\n"+this);
@@ -272,42 +280,29 @@ public class String {
       dst[j++]=value[i+offset];
     return;
   }
-
+*/
   public int length() {
     return count;
   }
-
-  public char charAt(int i) {
+/*
+  public char charAt(@LOC("in") int i) {
     return value[i+offset];
   }
-
+*/
   public String toString() {
     return this;
   }
 
-  public static String valueOf(Object o) {
+  public static String valueOf(@LOC("in") Object o) {
     if (o==null)
       return "null";
     else
       return o.toString();
   }
-
-  public static String valueOf(boolean b) {
-    if (b)
-      return new String("true");
-    else
-      return new String("false");
-  }
-
-  public static String valueOf(char c) {
-    char ar[]=new char[1];
-    ar[0]=c;
-    return new String(ar);
-  }
-
-  public static String valueOf(int x) {
-    int length=0;
-    int tmp;
+  
+  public static String valueOf(@LOC("in") int x) {
+    @LOC("in") int length=0;
+    @LOC("in") int tmp;
     if (x<0)
       tmp=-x;
     else
@@ -317,12 +312,12 @@ public class String {
       length=length+1;
     } while(tmp!=0);
 
-    char chararray[];
+    @LOC("in") char chararray[];
     if (x<0)
       chararray=new char[length+1];
     else
       chararray=new char[length];
-    int voffset;
+    @LOC("in") int voffset;
     if (x<0) {
       chararray[0]='-';
       voffset=1;
@@ -336,8 +331,24 @@ public class String {
     } while (length!=0);
     return new String(chararray);
   }
+  
+/*
+  public static String valueOf(@LOC("in") boolean b) {
+    if (b)
+      return new String("true");
+    else
+      return new String("false");
+  }
+
+  public static String valueOf(@LOC("in") char c) {
+    @LOC("data") char ar[]=new char[1];
+    ar[0]=c;
+    return new String(ar);
+  }
 
-  public static String valueOf(double val) {
+  
+
+  public static String valueOf(@LOC("in") double val) {
     char[] chararray=new char[20];
     String s=new String();
     s.offset=0;
@@ -345,10 +356,10 @@ public class String {
     s.value=chararray;
     return s;
   }
-  
+
   public static native int convertdoubletochar(double val, char [] chararray);
 
-  public static String valueOf(long x) {
+  public static String valueOf(@LOC("in") long x) {
     int length=0;
     long tmp;
     if (x<0)
@@ -380,57 +391,57 @@ public class String {
     return new String(chararray);
   }
 
-  public int compareTo(String s) {
+  public int compareTo(@LOC("in") String s) {
     int smallerlength=count<s.count?count:s.count;
 
     for( int i = 0; i < smallerlength; i++ ) {
       int valDiff = this.charAt(i) - s.charAt(i);
       if( valDiff != 0 ) {
-       return valDiff;
+        return valDiff;
       }
     }
     return count-s.count;
   }
-
+*/
   public int hashCode() {
     if (cachedHashcode!=0)
       return cachedHashcode;
-    int hashcode=0;
-    for(int i=0; i<count; i++)
+    @LOC("data") int hashcode=0;
+    for(@LOC("c") int i=0; i<count; i++)
       hashcode=hashcode*31+value[i+offset];
     cachedHashcode=hashcode;
     return hashcode;
   }
 
-  public boolean equals(Object o) {
+  public boolean equals(@LOC("in") Object o) {
     if (o.getType()!=getType())
       return false;
-    String s=(String)o;
+    @LOC("in") String s=(String)o;
     if (s.count!=count)
       return false;
-    for(int i=0; i<count; i++) {
+    for(@LOC("c") int i=0; i<count; i++) {
       if (s.value[i+s.offset]!=value[i+offset])
-       return false;
+        return false;
     }
     return true;
   }
-
-  public boolean equalsIgnoreCase(String s) {
+  /*
+  public boolean equalsIgnoreCase(@LOC("in") String s) {
     if (s.count!=count)
       return false;
     for(int i=0; i<count; i++) {
       char l=s.value[i+s.offset];
       char r=value[i+offset];
       if (l>='a'&&l<='z')
-       l=(char)((l-'a')+'A');
+        l=(char)((l-'a')+'A');
       if (r>='a'&&r<='z')
-       r=(char)((r-'a')+'A');
+        r=(char)((r-'a')+'A');
       if (l!=r)
-       return false;
+        return false;
     }
     return true;
   }
-/*
+
   public Vector split() {
     Vector splitted = new Vector();
     int i;
@@ -469,11 +480,11 @@ public class String {
        t.count=i-oldi;
        splitted.addElement(t);
     }
-    
+
     return splitted;
   }
-*/
-  public boolean contains(String str)
+   
+  public boolean contains(@LOC("in") String str)
   {
     int i,j;
     char[] strChar = str.toCharArray();
@@ -494,12 +505,12 @@ public class String {
     return false;
 
   }
-  
+
   public String trim() {
     int len = count;
     int st = 0;
-    int off = offset;      /* avoid getfield opcode */
-    char[] val = value;    /* avoid getfield opcode */
+    int off = offset;      //avoid getfield opcode 
+    char[] val = value;    // avoid getfield opcode 
 
     while ((st < len) && (val[off + st] <= ' ')) {
       st++;
@@ -509,9 +520,10 @@ public class String {
     }
     return ((st > 0) || (len < count)) ? substring(st, len) : this;
   }
-  
-  public boolean matches(String regex) {
+
+  public boolean matches(@LOC("in") String regex) {
     System.println("String.matches() is not fully supported");
     return this.equals(regex);
   }
+  */
 }