FileDocCategorySizeDatePackage
LocalVariables.javaAPI DocJava SE 5 API8125Fri Aug 26 14:55:26 BST 2005com.sun.org.apache.bcel.internal.verifier.structurals

LocalVariables

public class LocalVariables extends Object
This class implements an array of local variables used for symbolic JVM simulation.
version
$Id: LocalVariables.java,v 1.1.1.1 2001/10/29 20:00:41 jvanzyl Exp $
author
Enver Haase

Fields Summary
private Type[]
locals
The Type[] containing the local variable slots.
Constructors Summary
public LocalVariables(int maxLocals)
Creates a new LocalVariables object.

		locals = new Type[maxLocals];
		for (int i=0; i<maxLocals; i++){
			locals[i] = Type.UNKNOWN;
		}
	
Methods Summary
protected java.lang.Objectclone()
Returns a deep copy of this object; i.e. the clone operates on a new local variable array. However, the Type objects in the array are shared.

		LocalVariables lvs = new LocalVariables(locals.length);
		for (int i=0; i<locals.length; i++){
			lvs.locals[i] = this.locals[i];
		}
		return lvs;
	
public booleanequals(java.lang.Object o)

		if (!(o instanceof LocalVariables)) return false;
		LocalVariables lv = (LocalVariables) o;
		if (this.locals.length != lv.locals.length) return false;
		for (int i=0; i<this.locals.length; i++){
			if (!this.locals[i].equals(lv.locals[i])){
				//System.out.println(this.locals[i]+" is not "+lv.locals[i]);
				return false;
			}
		}
		return true;
	
public com.sun.org.apache.bcel.internal.generic.Typeget(int i)
Returns the type of the local variable slot i.

		return locals[i];
	
public com.sun.org.apache.bcel.internal.verifier.structurals.LocalVariablesgetClone()
Returns a (correctly typed) clone of this object. This is equivalent to ((LocalVariables) this.clone()).

		return (LocalVariables) this.clone();
	
public voidinitializeObject(UninitializedObjectType u)
Replaces all occurences of u in this local variables set with an "initialized" ObjectType.

		for (int i=0; i<locals.length; i++){
			if (locals[i] == u){
				locals[i] = u.getInitialized();
			}
		}
	
public intmaxLocals()
Returns the number of local variable slots this LocalVariables instance has.

		return locals.length;
	
public voidmerge(com.sun.org.apache.bcel.internal.verifier.structurals.LocalVariables lv)
Merges two local variables sets as described in the Java Virtual Machine Specification, Second Edition, section 4.9.2, page 146.


		if (this.locals.length != lv.locals.length){
			throw new AssertionViolatedException("Merging LocalVariables of different size?!? From different methods or what?!?");
		}

		for (int i=0; i<locals.length; i++){
			merge(lv, i);
		}
	
private voidmerge(com.sun.org.apache.bcel.internal.verifier.structurals.LocalVariables lv, int i)
Merges a single local variable.

see
#merge(LocalVariables)

		
		// We won't accept an unitialized object if we know it was initialized;
		// compare vmspec2, 4.9.4, last paragraph.
		if ( (!(locals[i] instanceof UninitializedObjectType)) && (lv.locals[i] instanceof UninitializedObjectType) ){
			throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
		}
		// Even harder, what about _different_ uninitialized object types?!
		if ( (!(locals[i].equals(lv.locals[i]))) && (locals[i] instanceof UninitializedObjectType) && (lv.locals[i] instanceof UninitializedObjectType) ){
			throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
		}
		// If we just didn't know that it was initialized, we have now learned.
		if (locals[i] instanceof UninitializedObjectType){
			if (! (lv.locals[i] instanceof UninitializedObjectType)){
				locals[i] = ((UninitializedObjectType) locals[i]).getInitialized();
			}
		}
		if ((locals[i] instanceof ReferenceType) && (lv.locals[i] instanceof ReferenceType)){
			if (! locals[i].equals(lv.locals[i])){ // needed in case of two UninitializedObjectType instances
				Type sup = ((ReferenceType) locals[i]).firstCommonSuperclass((ReferenceType) (lv.locals[i]));

				if (sup != null){
					locals[i] = sup;
				}
				else{
					// We should have checked this in Pass2!
					throw new AssertionViolatedException("Could not load all the super classes of '"+locals[i]+"' and '"+lv.locals[i]+"'.");
				}
			}
		}
		else{
			if (! (locals[i].equals(lv.locals[i])) ){
/*TODO
				if ((locals[i] instanceof com.sun.org.apache.bcel.internal.generic.ReturnaddressType) && (lv.locals[i] instanceof com.sun.org.apache.bcel.internal.generic.ReturnaddressType)){
					//System.err.println("merging "+locals[i]+" and "+lv.locals[i]);
					throw new AssertionViolatedException("Merging different ReturnAddresses: '"+locals[i]+"' and '"+lv.locals[i]+"'.");
				}
*/
				locals[i] = Type.UNKNOWN;
			}
		}
	
public voidset(int i, com.sun.org.apache.bcel.internal.generic.Type type)
Sets a new Type for the given local variable slot.

		if (type == Type.BYTE || type == Type.SHORT || type == Type.BOOLEAN || type == Type.CHAR){
			throw new AssertionViolatedException("LocalVariables do not know about '"+type+"'. Use Type.INT instead.");
		}
		locals[i] = type;
	
public java.lang.StringtoString()
Returns a String representation of this object.

		String s = new String();
		for (int i=0; i<locals.length; i++){
			s += Integer.toString(i)+": "+locals[i]+"\n";
		}
		return s;