Coverage Report - org.apache.commons.javaflow.bytecode.transformation.bcel.analyser.Frame
 
Classes in this File Line Coverage Branch Coverage Complexity
Frame
0%
0/44
0%
0/36
3.556
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser;
 18  
 
 19  
 import org.apache.bcel.generic.Type;
 20  
 import org.apache.bcel.generic.ReferenceType;
 21  
 import org.apache.bcel.generic.ReturnaddressType;
 22  
 import org.apache.bcel.verifier.exc.StructuralCodeConstraintException;
 23  
 import org.apache.bcel.verifier.exc.AssertionViolatedException;
 24  
 
 25  
 /**
 26  
  * This class represents a JVM execution frame; that means,
 27  
  * a local variable array and an operand stack.
 28  
  * 
 29  
  * WARNING! These classes are a fork of the bcel verifier.
 30  
  *
 31  
  * @version $Id: Frame.java 480487 2006-11-29 08:54:42Z bayard $
 32  
  * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A>
 33  
  */
 34  
 
 35  
 public class Frame{
 36  
 
 37  
     /**
 38  
      * For instance initialization methods, it is important to remember
 39  
      * which instance it is that is not initialized yet. It will be
 40  
      * initialized invoking another constructor later.
 41  
      * NULL means the instance already *is* initialized.
 42  
      */
 43  
     public static UninitializedObjectType _this;
 44  
 
 45  
     /**
 46  
      *
 47  
      */
 48  
     private LocalVariables locals;
 49  
 
 50  
     /**
 51  
      *
 52  
      */
 53  
     private OperandStack stack;
 54  
 
 55  
     /**
 56  
      *
 57  
      */
 58  0
     public Frame(int maxLocals, int maxStack){
 59  0
         locals = new LocalVariables(maxLocals);
 60  0
         stack = new OperandStack(maxStack);
 61  0
     }
 62  
 
 63  
     /**
 64  
      *
 65  
      */
 66  0
     public Frame(LocalVariables locals, OperandStack stack){
 67  0
         this.locals = locals;
 68  0
         this.stack = stack;
 69  0
     }
 70  
 
 71  
     /**
 72  
      *
 73  
      */
 74  
     protected Object clone(){
 75  0
         Frame f = new Frame(locals.getClone(), stack.getClone());
 76  0
         return f;
 77  
     }
 78  
 
 79  
     /**
 80  
      *
 81  
      */
 82  
     public Frame getClone(){
 83  0
         return (Frame) clone();
 84  
     }
 85  
 
 86  
     /**
 87  
      *
 88  
      */
 89  
     public LocalVariables getLocals(){
 90  0
         return locals;
 91  
     }
 92  
 
 93  
     /**
 94  
      *
 95  
      */
 96  
     public OperandStack getStack(){
 97  0
         return stack;
 98  
     }
 99  
 
 100  
     /**
 101  
      *
 102  
      */
 103  
     public boolean equals(Object o){
 104  0
         if (!(o instanceof Frame)) return false; // implies "null" is non-equal.
 105  0
         Frame f = (Frame) o;
 106  0
         return this.stack.equals(f.stack) && this.locals.equals(f.locals);
 107  
     }
 108  
 
 109  
     /**
 110  
      * Returns a String representation of the Frame instance.
 111  
      */
 112  
     public String toString(){
 113  0
         String s="Local Variables:\n";
 114  0
         s += locals;
 115  0
         s += "OperandStack:\n";
 116  0
         s += stack;
 117  0
         return s;
 118  
     }
 119  
 
 120  
 
 121  
     /**
 122  
      * Merges two {@link Type}s into one.
 123  
      *
 124  
      * @param errorIfFailed
 125  
      *      if true, attempting to merge two types that are incompatible causes an error.
 126  
      *      if false, it yields {@link Type#UNKNOWN} value, indicating that value is unusable.
 127  
      */
 128  
     /*package*/ static Type merge(Type lhs, Type rhs, boolean errorIfFailed) {
 129  
         try {
 130  
 
 131  
             // We won't accept an unitialized object if we know it was initialized;
 132  
             // compare vmspec2, 4.9.4, last paragraph.
 133  0
             if ((!(lhs instanceof UninitializedObjectType)) && (rhs instanceof UninitializedObjectType)) {
 134  0
                 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
 135  
             }
 136  
             // Even harder, what about _different_ uninitialized object types?!
 137  0
             if ((!(lhs.equals(rhs))) && (lhs instanceof UninitializedObjectType) && (rhs instanceof UninitializedObjectType)) {
 138  0
                 throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
 139  
             }
 140  
             // If we just didn't know that it was initialized, we have now learned.
 141  0
             if (lhs instanceof UninitializedObjectType) {
 142  0
                 if (! (rhs instanceof UninitializedObjectType)) {
 143  0
                     lhs = ((UninitializedObjectType) lhs).getInitialized();
 144  
                 }
 145  
             }
 146  0
             if ((lhs instanceof ReferenceType) && (rhs instanceof ReferenceType)) {
 147  0
                 if(lhs.equals(rhs)) {
 148  0
                     return lhs; // same type
 149  
                 }
 150  
 
 151  0
                 Type sup = ((ReferenceType) lhs).getFirstCommonSuperclass((ReferenceType) rhs);
 152  
 
 153  0
                 if (sup != null) {
 154  0
                     return sup;
 155  
                 } else {
 156  
                     // We should have checked this in Pass2!
 157  0
                     throw new AssertionViolatedException("Could not load all the super classes of '" + lhs + "' and '" + rhs + "'.");
 158  
                 }
 159  
             }
 160  
 
 161  0
             if ((lhs instanceof ReturnaddressType) && (rhs instanceof ReturnaddressType)) {
 162  
                 // see 'FinallyFlow' test.
 163  0
                 return lhs;
 164  
             }
 165  
 
 166  0
             if (!lhs.equals(rhs)) {
 167  0
                 if(errorIfFailed) {
 168  0
                     throw new StructuralCodeConstraintException("Cannot merge different types:"+lhs+" and "+rhs);
 169  
                 } else {
 170  0
                     return Type.UNKNOWN;
 171  
                 }
 172  
             }
 173  
 
 174  0
             return lhs;
 175  0
         } catch (ClassNotFoundException e) {
 176  
             // FIXME: maybe not the best way to handle this
 177  0
             throw new AssertionViolatedException("Missing class: " + e.toString());
 178  
         }
 179  
     }
 180  
 }