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

heros.fieldsens.ControlFlowJoinResolver Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2015 Johannes Lerch.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Johannes Lerch - initial API and implementation
 ******************************************************************************/
package heros.fieldsens;

import heros.fieldsens.AccessPath.Delta;
import heros.fieldsens.structs.DeltaConstraint;
import heros.fieldsens.structs.WrappedFact;
import heros.fieldsens.structs.WrappedFactAtStatement;

public class ControlFlowJoinResolver extends ResolverTemplate> {

	private Stmt joinStmt;
	private boolean propagated = false;
	private Fact sourceFact;
	private FactMergeHandler factMergeHandler;

	public ControlFlowJoinResolver(FactMergeHandler factMergeHandler, PerAccessPathMethodAnalyzer analyzer, Stmt joinStmt, Debugger debugger) {
		this(factMergeHandler, analyzer, joinStmt, null, new AccessPath(), debugger, null);
		this.factMergeHandler = factMergeHandler;
		propagated=false;
	}
	
	private ControlFlowJoinResolver(FactMergeHandler factMergeHandler, PerAccessPathMethodAnalyzer analyzer, 
			Stmt joinStmt, Fact sourceFact, AccessPath resolvedAccPath, Debugger debugger, ControlFlowJoinResolver parent) {
		super(analyzer, resolvedAccPath, parent, debugger);
		this.factMergeHandler = factMergeHandler;
		this.joinStmt = joinStmt;
		this.sourceFact = sourceFact;
		propagated=true;
	}
	
	@Override
	protected AccessPath getAccessPathOf(WrappedFact inc) {
		return inc.getAccessPath();
	}

	protected void processIncomingGuaranteedPrefix(heros.fieldsens.structs.WrappedFact fact) {
		if(propagated) {
			factMergeHandler.merge(sourceFact, fact.getFact());
		}
		else {
			propagated=true;
			sourceFact = fact.getFact();
			analyzer.processFlowFromJoinStmt(new WrappedFactAtStatement(joinStmt, new WrappedFact(
					fact.getFact(), new AccessPath(), this)));
		}
	};
	
	private boolean isNullOrCallEdgeResolver(Resolver resolver) {
		if(resolver == null)
			return true;
		if(resolver instanceof CallEdgeResolver) {
			return !(resolver instanceof ZeroCallEdgeResolver);
		}
		return false;
	}
	
	@Override
	protected void processIncomingPotentialPrefix(final WrappedFact fact) {
		if(isNullOrCallEdgeResolver(fact.getResolver())) {
			canBeResolvedEmpty();
		}
		else {
			lock();
			Delta delta = fact.getAccessPath().getDeltaTo(resolvedAccessPath);
			fact.getResolver().resolve(new DeltaConstraint(delta), new InterestCallback() {
				@Override
				public void interest(PerAccessPathMethodAnalyzer analyzer, 
						Resolver resolver) {
					ControlFlowJoinResolver.this.interest(resolver);
				}
	
				@Override
				public void canBeResolvedEmpty() {
					ControlFlowJoinResolver.this.canBeResolvedEmpty();
				}
			});
			unlock();
		}
	}
	
	@Override
	protected ResolverTemplate> createNestedResolver(AccessPath newAccPath) {
		return new ControlFlowJoinResolver(factMergeHandler, analyzer, joinStmt, sourceFact, newAccPath, debugger, this);
	}

	@Override
	protected void log(String message) {
		analyzer.log("Join Stmt "+toString()+": "+message);
	}

	@Override
	public String toString() {
		return "<"+resolvedAccessPath+":"+joinStmt+" in "+analyzer.getMethod()+">";
	}

	public Stmt getJoinStmt() {
		return joinStmt;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy