Hi,

Here is a new patch to replace the former one on variable backpropagation. Previously
I missed an occurence of addMonitorVariable in JTryFinallyStatement.java. Again the
former code could mess up the variables and be the source of really strange NullPointerException.
The test case, contributed by Helmer, is given in attachment. My new patch is also attached
the this e-mail.


Helmer, could you test Eclipse with this new patch ?

Cheers,

Guilhem.

P.S.: Jim, your patch to KJC seems to pose problems when I run "javac test.java" (or anything other program)
To be able to compile a Java file you need now to always provide "-d ."
public class test
{
        public static void main (String args[])
        {
                try { } 
                finally {

                        synchronized (new Object()) {
                                int i = 0;      
                        }
                }       
        }
}
diff -ur kopi-2.1B.orig/src/bytecode/ssa/LivenessComputer.java 
kopi-2.1B/src/bytecode/ssa/LivenessComputer.java
--- kopi-2.1B.orig/src/bytecode/ssa/LivenessComputer.java       2002-07-15 
20:53:29.000000000 +0200
+++ kopi-2.1B/src/bytecode/ssa/LivenessComputer.java    2003-07-31 09:00:34.000000000 
+0200
@@ -334,7 +334,7 @@
                if (phi instanceof QPhiCatch) {
 
                    //compute temp = (use[ij] - def[i1i2..i(j-1)]).
-                   temp.clear();
+                   for (int u=0;u<temp.size();u++) temp.clear(u);;
                    QOperandBox[] operands = phi.getUses();
                    for (int u = 0; u < operands.length; ++u) {
                        if (operands[u].getOperand() instanceof QSSAVar) {
@@ -360,7 +360,7 @@
            while (insts.hasNext()) {
 
                //compute temp = (use[ij] - def[i1i2..i(j-1)]).
-               temp.clear();
+               for (int u=0;u<temp.size();u++) temp.clear(u);;
                QInst inst = (QInst) insts.next();
                QOperandBox[] operands = inst.getUses();
                for (int u = 0; u < operands.length; ++u) {
@@ -434,7 +434,7 @@
 
 
                //out[n] = union {s in succ[n]}  in[s]
-               out.clear();
+               for (int u=0;u<out.size();u++) out.clear(u);
                Iterator succs = nodes[nodeIndex].getSuccessors();
                while (succs.hasNext()) {
                    out.or(ins[((Node)succs.next()).getIndex()]);
@@ -491,7 +491,7 @@
            while (insts.hasNext()) {
 
                //compute temp = (use[ij] - def[i1i2..i(j-1)]).
-               temp.clear();
+               for (int u=0;u<temp.size();u++) temp.clear(u);
                QInst inst = (QInst) insts.next();
                QOperandBox[] operands = inst.getUses();
                for (int u = 0; u < operands.length; ++u) {
@@ -530,7 +530,7 @@
 
 
                //out[n] = union {s in succ[n]}  in[s]
-               out.clear();
+               for (int u=0;u<out.size();u++) out.clear(u);
                Iterator succs = nodes[nodeIndex].getSuccessors();
                while (succs.hasNext()) {
                    out.or(ins[((Node)succs.next()).getIndex()]);
diff -ur kopi-2.1B.orig/src/kjc/CBlockContext.java kopi-2.1B/src/kjc/CBlockContext.java
--- kopi-2.1B.orig/src/kjc/CBlockContext.java   2002-07-15 20:53:32.000000000 +0200
+++ kopi-2.1B/src/kjc/CBlockContext.java        2003-07-31 09:26:59.000000000 +0200
@@ -59,6 +59,8 @@
     this.localVars = localVars == 0 ? null : new ArrayList(localVars);
     this.localsPosition = 0;
     this.parentIndex = 0;
+    this.localsIndex = 0;
+    this.childrenBlock = null;
   }
 
   /**
@@ -81,11 +83,15 @@
     super(parent, environment);
 
     this.localVars = new ArrayList(predictedVars);
+    this.childrenBlock = null;
 
     CBlockContext      parentBlock = parent.getBlockContext();
 
     this.localsPosition = parentBlock.localsPosition();
+    this.localsIndex = 0;
     this.parentIndex = parentBlock.localsIndex();
+
+    parentBlock.registerChildBlock(this);
   }
 
   // ----------------------------------------------------------------------
@@ -165,6 +171,61 @@
     localsPosition += var.getType().getSize();
   }
 
+  public void registerChildBlock(CBlockContext child) {
+     if (childrenBlock == null) {
+        childrenBlock = new ArrayList();
+     }
+     childrenBlock.add(child);
+  }
+
+  /**
+   * Fix the position of local variables as a monitor variable has been
+   * added to the stack.
+   * 
+   * @param     incr     the update increment for local variables
+   */
+  public void fixVariablePositions(int increment) throws UnpositionedError {
+       localsPosition += increment;
+       parentIndex++;
+       for (int i=0; i < localVars.size(); i++) {
+           JLocalVariable  localVar = (JLocalVariable) localVars.get(i);
+
+           localVar.setPosition(localVar.getPosition()+increment);
+        // fix 27.03.02 lackner
+        // synthetic variable has no entry in CVariableInfo
+        // not necessary  think
+        //  localVar.setIndex(localVar.getIndex()+1);
+       }
+
+       if (childrenBlock != null) {
+         for (int i=0; i < childrenBlock.size(); i++) {
+          CBlockContext child = (CBlockContext)childrenBlock.get(i);
+          
+          child.fixVariablePositions(increment);
+         }
+       }
+  }
+
+  /**
+   * Adds a variable and fix the position of the current children block. This
+   * function is principally used by addMonitorVariable because child blocks
+   * may want to add some variable to the top of the analyse tree.
+   *
+   * @param    var     variable to insert
+   */
+  public void addVariableWithFix(JLocalVariable var) throws UnpositionedError {
+      int increment = var.getType().getSize();
+
+      addVariable(var);
+      if (childrenBlock != null) {
+        for (int i=0; i < childrenBlock.size(); i++) {
+          CBlockContext child = (CBlockContext)childrenBlock.get(i);
+          
+          child.fixVariablePositions(increment);
+        }
+      }
+  }
+
   /**
    * Adds the variable for the monitor of the synchronized statement to the 
    * correct context.
@@ -173,23 +234,9 @@
    */
   public void addMonitorVariable(JLocalVariable var)  throws UnpositionedError {
     if (parent instanceof CMethodContext) {
-      addVariable(var);
+      addVariableWithFix(var);
     } else {
       parent.addMonitorVariable(var);
-      // correct index
-      int       size = var.getType().getSize();
-
-      localsPosition += size;
-      parentIndex++;
-      for (int i=0; i < localVars.size(); i++) {
-        JLocalVariable  localVar = (JLocalVariable) localVars.get(i);
-
-        localVar.setPosition(localVar.getPosition()+size);
-        // fix 27.03.02 lackner
-        // synthetic variable has no entry in CVariableInfo
-        // not necessary  think
-        //  localVar.setIndex(localVar.getIndex()+1);
-      }
     }
   }
   /**
@@ -287,6 +334,7 @@
 
   private Hashtable                            localClasses;
   private ArrayList                            localVars;
+  private ArrayList                            childrenBlock;
 
   private /*final*/ int                                parentIndex;
   private int                                  localsIndex;
diff -ur kopi-2.1B.orig/src/kjc/JTryFinallyStatement.java 
kopi-2.1B/src/kjc/JTryFinallyStatement.java
--- kopi-2.1B.orig/src/kjc/JTryFinallyStatement.java    2002-07-15 20:53:32.000000000 
+0200
+++ kopi-2.1B/src/kjc/JTryFinallyStatement.java 2003-07-31 09:27:44.000000000 +0200
@@ -78,7 +78,7 @@
   public void analyse(CBodyContext context) throws PositionedError {
     CBlockContext      self = new CBlockContext(context, context.getEnvironment()){
         public void addMonitorVariable(JLocalVariable var)  throws UnpositionedError {
-          addVariable(var);
+          addVariableWithFix(var);
         }
       };
     CType               integerType = 
context.getTypeFactory().getPrimitiveType(TypeFactory.PRM_INT);

Reply via email to