1. package com.sun.org.apache.bcel.internal.verifier.structurals;
  2. /* ====================================================================
  3. * The Apache Software License, Version 1.1
  4. *
  5. * Copyright (c) 2001 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Apache" and "Apache Software Foundation" and
  28. * "Apache BCEL" must not be used to endorse or promote products
  29. * derived from this software without prior written permission. For
  30. * written permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * "Apache BCEL", nor may "Apache" appear in their name, without
  34. * prior written permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation. For more
  52. * information on the Apache Software Foundation, please see
  53. * <http://www.apache.org/>.
  54. */
  55. import com.sun.org.apache.bcel.internal.generic.Type;
  56. import com.sun.org.apache.bcel.internal.generic.ReferenceType;
  57. import com.sun.org.apache.bcel.internal.verifier.exc.*;
  58. /**
  59. * This class implements an array of local variables used for symbolic JVM
  60. * simulation.
  61. *
  62. * @version $Id: LocalVariables.java,v 1.1.1.1 2001/10/29 20:00:41 jvanzyl Exp $
  63. * @author <A HREF="http://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A>
  64. */
  65. public class LocalVariables{
  66. /** The Type[] containing the local variable slots. */
  67. private Type[] locals;
  68. /**
  69. * Creates a new LocalVariables object.
  70. */
  71. public LocalVariables(int maxLocals){
  72. locals = new Type[maxLocals];
  73. for (int i=0; i<maxLocals; i++){
  74. locals[i] = Type.UNKNOWN;
  75. }
  76. }
  77. /**
  78. * Returns a deep copy of this object; i.e. the clone
  79. * operates on a new local variable array.
  80. * However, the Type objects in the array are shared.
  81. */
  82. protected Object clone(){
  83. LocalVariables lvs = new LocalVariables(locals.length);
  84. for (int i=0; i<locals.length; i++){
  85. lvs.locals[i] = this.locals[i];
  86. }
  87. return lvs;
  88. }
  89. /**
  90. * Returns the type of the local variable slot i.
  91. */
  92. public Type get(int i){
  93. return locals[i];
  94. }
  95. /**
  96. * Returns a (correctly typed) clone of this object.
  97. * This is equivalent to ((LocalVariables) this.clone()).
  98. */
  99. public LocalVariables getClone(){
  100. return (LocalVariables) this.clone();
  101. }
  102. /**
  103. * Returns the number of local variable slots this
  104. * LocalVariables instance has.
  105. */
  106. public int maxLocals(){
  107. return locals.length;
  108. }
  109. /**
  110. * Sets a new Type for the given local variable slot.
  111. */
  112. public void set(int i, Type type){
  113. if (type == Type.BYTE || type == Type.SHORT || type == Type.BOOLEAN || type == Type.CHAR){
  114. throw new AssertionViolatedException("LocalVariables do not know about '"+type+"'. Use Type.INT instead.");
  115. }
  116. locals[i] = type;
  117. }
  118. /*
  119. * Fulfills the general contract of Object.equals().
  120. */
  121. public boolean equals(Object o){
  122. if (!(o instanceof LocalVariables)) return false;
  123. LocalVariables lv = (LocalVariables) o;
  124. if (this.locals.length != lv.locals.length) return false;
  125. for (int i=0; i<this.locals.length; i++){
  126. if (!this.locals[i].equals(lv.locals[i])){
  127. //System.out.println(this.locals[i]+" is not "+lv.locals[i]);
  128. return false;
  129. }
  130. }
  131. return true;
  132. }
  133. /**
  134. * Merges two local variables sets as described in the Java Virtual Machine Specification,
  135. * Second Edition, section 4.9.2, page 146.
  136. */
  137. public void merge(LocalVariables lv){
  138. if (this.locals.length != lv.locals.length){
  139. throw new AssertionViolatedException("Merging LocalVariables of different size?!? From different methods or what?!?");
  140. }
  141. for (int i=0; i<locals.length; i++){
  142. merge(lv, i);
  143. }
  144. }
  145. /**
  146. * Merges a single local variable.
  147. *
  148. * @see #merge(LocalVariables)
  149. */
  150. private void merge(LocalVariables lv, int i){
  151. // We won't accept an unitialized object if we know it was initialized;
  152. // compare vmspec2, 4.9.4, last paragraph.
  153. if ( (!(locals[i] instanceof UninitializedObjectType)) && (lv.locals[i] instanceof UninitializedObjectType) ){
  154. throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
  155. }
  156. // Even harder, what about _different_ uninitialized object types?!
  157. if ( (!(locals[i].equals(lv.locals[i]))) && (locals[i] instanceof UninitializedObjectType) && (lv.locals[i] instanceof UninitializedObjectType) ){
  158. throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
  159. }
  160. // If we just didn't know that it was initialized, we have now learned.
  161. if (locals[i] instanceof UninitializedObjectType){
  162. if (! (lv.locals[i] instanceof UninitializedObjectType)){
  163. locals[i] = ((UninitializedObjectType) locals[i]).getInitialized();
  164. }
  165. }
  166. if ((locals[i] instanceof ReferenceType) && (lv.locals[i] instanceof ReferenceType)){
  167. if (! locals[i].equals(lv.locals[i])){ // needed in case of two UninitializedObjectType instances
  168. Type sup = ((ReferenceType) locals[i]).firstCommonSuperclass((ReferenceType) (lv.locals[i]));
  169. if (sup != null){
  170. locals[i] = sup;
  171. }
  172. else{
  173. // We should have checked this in Pass2!
  174. throw new AssertionViolatedException("Could not load all the super classes of '"+locals[i]+"' and '"+lv.locals[i]+"'.");
  175. }
  176. }
  177. }
  178. else{
  179. if (! (locals[i].equals(lv.locals[i])) ){
  180. /*TODO
  181. if ((locals[i] instanceof com.sun.org.apache.bcel.internal.generic.ReturnaddressType) && (lv.locals[i] instanceof com.sun.org.apache.bcel.internal.generic.ReturnaddressType)){
  182. //System.err.println("merging "+locals[i]+" and "+lv.locals[i]);
  183. throw new AssertionViolatedException("Merging different ReturnAddresses: '"+locals[i]+"' and '"+lv.locals[i]+"'.");
  184. }
  185. */
  186. locals[i] = Type.UNKNOWN;
  187. }
  188. }
  189. }
  190. /**
  191. * Returns a String representation of this object.
  192. */
  193. public String toString(){
  194. String s = new String();
  195. for (int i=0; i<locals.length; i++){
  196. s += Integer.toString(i)+": "+locals[i]+"\n";
  197. }
  198. return s;
  199. }
  200. /**
  201. * Replaces all occurences of u in this local variables set
  202. * with an "initialized" ObjectType.
  203. */
  204. public void initializeObject(UninitializedObjectType u){
  205. for (int i=0; i<locals.length; i++){
  206. if (locals[i] == u){
  207. locals[i] = u.getInitialized();
  208. }
  209. }
  210. }
  211. }