All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.jimple.toolkits.pointer.PASideEffectTester Maven / Gradle / Ivy

There is a newer version: 2.5.0-9
Show newest version
/* Soot - a J*va Optimization Framework
 * Copyright (C) 2003 Ondrej Lhotak
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package soot.jimple.toolkits.pointer;

import soot.*;
import soot.jimple.*;
import java.util.*;

//  ArrayRef, 
//  CaughtExceptionRef, 
//  FieldRef, 
//  IdentityRef, 
//  InstanceFieldRef, 
//  InstanceInvokeExpr, 
//  Local,  
//  StaticFieldRef

public class PASideEffectTester implements SideEffectTester
{
    PointsToAnalysis pa = Scene.v().getPointsToAnalysis();
    SideEffectAnalysis sea = Scene.v().getSideEffectAnalysis();
    HashMap unitToRead;
    HashMap unitToWrite;
    HashMap localToReachingObjects;
    SootMethod currentMethod;

    public PASideEffectTester() {
	if( G.v().Union_factory == null ) {
	    G.v().Union_factory = new UnionFactory() {
		public Union newUnion() { return FullObjectSet.v(); }
	    };
	}
    }

    /** Call this when starting to analyze a new method to setup the cache. */
    public void newMethod( SootMethod m ) {
	unitToRead = new HashMap();
	unitToWrite = new HashMap();
	localToReachingObjects = new HashMap();
	currentMethod = m;
	sea.findNTRWSets( currentMethod );
    }

    protected RWSet readSet( Unit u ) {
	RWSet ret = unitToRead.get( u );
	if( ret == null ) {
	    unitToRead.put( u, ret = sea.readSet( currentMethod, (Stmt) u ) );
	}
	return ret;
    }

    protected RWSet writeSet( Unit u ) {
	RWSet ret = unitToWrite.get( u );
	if( ret == null ) {
	    unitToWrite.put( u, ret = sea.writeSet( currentMethod, (Stmt) u ) );
	}
	return ret;
    }
    
    protected PointsToSet reachingObjects( Local l ) {
	PointsToSet ret = localToReachingObjects.get( l );
	if( ret == null ) {
	    localToReachingObjects.put( l, 
		    ret = pa.reachingObjects( l ) );
	}
	return ret;
    }

    /** Returns true if the unit can read from v.
     * Does not deal with expressions; deals with Refs. */
    public boolean unitCanReadFrom(Unit u, Value v)
    {
	return valueTouchesRWSet( readSet( u ), v, u.getUseBoxes() );
    }

    /** Returns true if the unit can read from v.
     * Does not deal with expressions; deals with Refs. */
    public boolean unitCanWriteTo(Unit u, Value v)
    {
	return valueTouchesRWSet( writeSet( u ), v, u.getDefBoxes() );
    }

    protected boolean valueTouchesRWSet(RWSet s, Value v, List boxes)
    {
        for( Iterator useIt = v.getUseBoxes().iterator(); useIt.hasNext(); ) {
            final ValueBox use = (ValueBox) useIt.next();
            if( valueTouchesRWSet( s, use.getValue(), boxes ) ) return true;
        }
        // This doesn't really make any sense, but we need to return something.
        if (v instanceof Constant)
            return false;

        if (v instanceof Expr)
            throw new RuntimeException("can't deal with expr");

	for( Iterator boxIt = boxes.iterator(); boxIt.hasNext(); ) {

	    final ValueBox box = (ValueBox) boxIt.next();
	    Value boxed = box.getValue();
	    if( boxed.equivTo( v ) ) return true;
	}

	if (v instanceof Local) {
	    return false;
	}

	if( v instanceof InstanceFieldRef ) {
	    InstanceFieldRef ifr = (InstanceFieldRef) v;
	    if( s == null ) return false;
	    PointsToSet o1 = s.getBaseForField( ifr.getField() );
	    if( o1 == null ) return false;
	    PointsToSet o2 = reachingObjects( (Local) ifr.getBase() );
	    if( o2 == null ) return false;
	    return o1.hasNonEmptyIntersection( o2 );
	}

	if( v instanceof ArrayRef ) {
	    ArrayRef ar = (ArrayRef) v;
	    if( s == null ) return false;
	    PointsToSet o1 = s.getBaseForField( PointsToAnalysis.ARRAY_ELEMENTS_NODE );
	    if( o1 == null ) return false;
	    PointsToSet o2 = reachingObjects( (Local) ar.getBase() );
	    if( o2 == null ) return false;
	    return o1.hasNonEmptyIntersection( o2 );
	}

	if( v instanceof StaticFieldRef ) {
	    StaticFieldRef sfr = (StaticFieldRef) v;
	    if( s == null ) return false;
	    return s.getGlobals().contains( sfr.getField() );
	}

	throw new RuntimeException( "Forgot to handle value "+v );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy