2007-02-02 17:17:13 +00:00
|
|
|
/******************************************************************************
|
|
|
|
* Copyright (c) 2002 - 2006 IBM Corporation.
|
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
* Contributors:
|
|
|
|
* IBM Corporation - initial API and implementation
|
|
|
|
*****************************************************************************/
|
|
|
|
package com.ibm.wala.cast.ipa.callgraph;
|
|
|
|
|
2010-09-14 20:29:05 +00:00
|
|
|
import java.io.UTFDataFormatException;
|
2007-02-02 17:17:13 +00:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Set;
|
|
|
|
|
2008-02-05 19:08:29 +00:00
|
|
|
import com.ibm.wala.analysis.reflection.ReflectionContextInterpreter;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.cast.ipa.callgraph.AstCallGraph.AstCGNode;
|
|
|
|
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys.ScopeMappingInstanceKey;
|
2008-02-05 19:08:29 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstAssertInstruction;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.AstEchoInstruction;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.AstGlobalRead;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.AstGlobalWrite;
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
2008-02-05 19:08:29 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstInstructionVisitor;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.AstIsDefinedInstruction;
|
2011-05-23 16:27:07 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess;
|
2010-11-02 19:11:58 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
|
2008-02-05 19:08:29 +00:00
|
|
|
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.AstLexicalWrite;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.EachElementGetInstruction;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.EachElementHasNextInstruction;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
|
|
|
import com.ibm.wala.cast.loader.AstMethod;
|
|
|
|
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
|
2010-11-02 19:11:58 +00:00
|
|
|
import com.ibm.wala.classLoader.IClass;
|
2011-01-17 21:43:18 +00:00
|
|
|
import com.ibm.wala.fixpoint.AbstractOperator;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.fixpoint.IntSetVariable;
|
2011-01-17 21:43:18 +00:00
|
|
|
import com.ibm.wala.fixpoint.UnaryOperator;
|
2007-04-24 13:51:15 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
|
|
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
2017-02-03 01:33:27 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.IAnalysisCacheView;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
2007-07-06 22:09:29 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.AbstractFieldPointerKey;
|
2014-07-11 15:55:02 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
2007-07-06 22:09:29 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
2014-07-11 15:55:02 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
2007-07-06 22:09:29 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysisImpl;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerKeyFactory;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointsToMap;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointsToSetVariable;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
2014-07-11 15:55:02 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.PropagationSystem;
|
2007-07-06 22:09:29 +00:00
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.cfa.DefaultSSAInterpreter;
|
|
|
|
import com.ibm.wala.ipa.callgraph.propagation.cfa.DelegatingSSAContextInterpreter;
|
2007-06-01 03:31:35 +00:00
|
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
2014-07-11 15:55:02 +00:00
|
|
|
import com.ibm.wala.ipa.modref.ArrayLengthKey;
|
2007-04-24 13:51:15 +00:00
|
|
|
import com.ibm.wala.ssa.DefUse;
|
2017-03-11 18:22:45 +00:00
|
|
|
import com.ibm.wala.ssa.IRView;
|
2007-04-24 13:51:15 +00:00
|
|
|
import com.ibm.wala.ssa.SSAPutInstruction;
|
|
|
|
import com.ibm.wala.ssa.SymbolTable;
|
2007-07-11 21:07:32 +00:00
|
|
|
import com.ibm.wala.util.collections.HashSetFactory;
|
2007-02-02 17:17:13 +00:00
|
|
|
import com.ibm.wala.util.collections.Pair;
|
|
|
|
import com.ibm.wala.util.debug.Assertions;
|
2008-10-03 20:10:09 +00:00
|
|
|
import com.ibm.wala.util.intset.IntSet;
|
2007-04-24 13:51:15 +00:00
|
|
|
import com.ibm.wala.util.intset.IntSetAction;
|
|
|
|
import com.ibm.wala.util.intset.IntSetUtil;
|
|
|
|
import com.ibm.wala.util.intset.MutableIntSet;
|
|
|
|
import com.ibm.wala.util.intset.MutableMapping;
|
2015-04-06 01:19:56 +00:00
|
|
|
import com.ibm.wala.util.strings.Atom;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-02-09 15:33:45 +00:00
|
|
|
public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCallGraphBuilder {
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
public static final boolean DEBUG_TYPE_INFERENCE = false;
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-02-02 17:17:13 +00:00
|
|
|
public static final boolean DEBUG_PROPERTIES = false;
|
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
//
|
|
|
|
// language specialization interface
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
/**
|
|
|
|
* should we maintain an object catalog for each instance key, storing the
|
|
|
|
* names of all known properties of the instance key? required to handle
|
|
|
|
* {@link EachElementGetInstruction}s.
|
|
|
|
*
|
|
|
|
* @see AstConstraintVisitor#visitPut(SSAPutInstruction)
|
|
|
|
* @see AstConstraintVisitor#visitEachElementGet(EachElementGetInstruction)
|
|
|
|
*/
|
2007-02-02 17:17:13 +00:00
|
|
|
protected abstract boolean useObjectCatalog();
|
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
/**
|
|
|
|
* each language can specify whether a particular field name should be stored
|
|
|
|
* in object catalogs or not. By default, always return false.
|
|
|
|
*/
|
2010-11-02 19:11:58 +00:00
|
|
|
protected boolean isUncataloguedField(IClass type, String fieldName) {
|
|
|
|
return false;
|
|
|
|
}
|
2011-05-02 22:11:27 +00:00
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
//
|
|
|
|
// overall control
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2014-07-11 15:55:02 +00:00
|
|
|
|
2015-04-06 01:19:56 +00:00
|
|
|
public abstract GlobalObjectKey getGlobalObject(Atom language);
|
|
|
|
|
2017-02-03 01:33:27 +00:00
|
|
|
protected AstSSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, IAnalysisCacheView cache,
|
2011-05-02 22:11:27 +00:00
|
|
|
PointerKeyFactory pointerKeyFactory) {
|
2007-07-20 15:19:33 +00:00
|
|
|
super(cha, options, cache, pointerKeyFactory);
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2007-02-09 15:33:45 +00:00
|
|
|
public SSAContextInterpreter makeDefaultContextInterpreters(SSAContextInterpreter appContextInterpreter, AnalysisOptions options,
|
2010-05-12 17:19:54 +00:00
|
|
|
IClassHierarchy cha) {
|
2007-07-20 15:19:33 +00:00
|
|
|
SSAContextInterpreter c = new DefaultSSAInterpreter(options, getAnalysisCache());
|
|
|
|
c = new DelegatingSSAContextInterpreter(new AstContextInsensitiveSSAContextInterpreter(options, getAnalysisCache()), c);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
c = new DelegatingSSAContextInterpreter(ReflectionContextInterpreter.createReflectionContextInterpreter(cha, options,
|
|
|
|
getAnalysisCache()), c);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
|
|
|
if (appContextInterpreter == null)
|
|
|
|
return c;
|
|
|
|
else
|
|
|
|
return new DelegatingSSAContextInterpreter(appContextInterpreter, c);
|
|
|
|
}
|
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
//
|
|
|
|
// specialized pointer analysis
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2014-07-11 15:55:02 +00:00
|
|
|
@Override
|
|
|
|
protected PropagationSystem makeSystem(AnalysisOptions options) {
|
|
|
|
return new PropagationSystem(callGraph, pointerKeyFactory, instanceKeyFactory) {
|
|
|
|
@Override
|
2014-07-30 13:05:15 +00:00
|
|
|
public PointerAnalysis<InstanceKey> makePointerAnalysis(PropagationCallGraphBuilder builder) {
|
2014-07-11 15:55:02 +00:00
|
|
|
return new AstPointerAnalysisImpl(builder, cg, pointsToMap, instanceKeys, pointerKeyFactory, instanceKeyFactory);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
public static class AstPointerAnalysisImpl extends PointerAnalysisImpl {
|
2007-04-19 13:48:01 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
public AstPointerAnalysisImpl(PropagationCallGraphBuilder builder, CallGraph cg, PointsToMap pointsToMap,
|
|
|
|
MutableMapping<InstanceKey> instanceKeys, PointerKeyFactory pointerKeys, InstanceKeyFactory iKeyFactory) {
|
|
|
|
super(builder, cg, pointsToMap, instanceKeys, pointerKeys, iKeyFactory);
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
|
|
|
|
2014-07-11 15:55:02 +00:00
|
|
|
@Override
|
|
|
|
protected HeapModel makeHeapModel() {
|
|
|
|
class Model extends HModel implements AstHeapModel {
|
|
|
|
@Override
|
|
|
|
public PointerKey getPointerKeyForArrayLength(InstanceKey I) {
|
|
|
|
return new ArrayLengthKey(I);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Iterator<PointerKey> getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
|
|
|
|
return ((AstPointerKeyFactory)pointerKeys).getPointerKeysForReflectedFieldRead(I, F);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
|
|
|
return ((AstPointerKeyFactory)pointerKeys).getPointerKeysForReflectedFieldWrite(I, F);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public PointerKey getPointerKeyForObjectCatalog(InstanceKey I) {
|
|
|
|
return ((AstPointerKeyFactory)pointerKeys).getPointerKeyForObjectCatalog(I);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Model();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
protected ImplicitPointsToSetVisitor makeImplicitPointsToVisitor(LocalPointerKey lpk) {
|
|
|
|
return new AstImplicitPointsToSetVisitor(this, lpk);
|
|
|
|
}
|
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
public static class AstImplicitPointsToSetVisitor extends ImplicitPointsToSetVisitor implements AstInstructionVisitor {
|
|
|
|
public AstImplicitPointsToSetVisitor(AstPointerAnalysisImpl analysis, LocalPointerKey lpk) {
|
|
|
|
super(analysis, lpk);
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitAstLexicalRead(AstLexicalRead instruction) {
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitAstLexicalWrite(AstLexicalWrite instruction) {
|
|
|
|
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
2007-06-06 20:15:48 +00:00
|
|
|
pointsToSet = analysis.computeImplicitPointsToSetAtGet(node, instruction.getDeclaredField(), -1, true);
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-02 22:11:27 +00:00
|
|
|
public void visitAssert(AstAssertInstruction instruction) {
|
2007-06-06 20:15:48 +00:00
|
|
|
|
|
|
|
}
|
2007-04-19 13:48:01 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitEachElementGet(EachElementGetInstruction inst) {
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitIsDefined(AstIsDefinedInstruction inst) {
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
2011-05-02 22:11:27 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-12-10 04:26:21 +00:00
|
|
|
public void visitEcho(AstEchoInstruction inst) {
|
|
|
|
|
|
|
|
}
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
2017-07-12 23:54:57 +00:00
|
|
|
}
|
2007-04-19 13:48:01 +00:00
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
//
|
|
|
|
// top-level node constraint generation
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
protected ExplicitCallGraph createEmptyCallGraph(IClassHierarchy cha, AnalysisOptions options) {
|
2007-07-20 15:19:33 +00:00
|
|
|
return new AstCallGraph(cha, options, getAnalysisCache());
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
public static class AstInterestingVisitor extends InterestingVisitor implements AstInstructionVisitor {
|
|
|
|
|
|
|
|
public AstInterestingVisitor(int vn) {
|
2007-02-02 17:17:13 +00:00
|
|
|
super(vn);
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitAstLexicalRead(AstLexicalRead instruction) {
|
|
|
|
bingo = true;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitAstLexicalWrite(AstLexicalWrite instruction) {
|
|
|
|
bingo = true;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
|
|
|
bingo = true;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
2007-02-09 15:33:45 +00:00
|
|
|
bingo = true;
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitAssert(AstAssertInstruction instruction) {
|
|
|
|
bingo = true;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitEachElementGet(EachElementGetInstruction inst) {
|
|
|
|
bingo = true;
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-02-02 17:17:13 +00:00
|
|
|
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
|
|
|
|
|
|
|
}
|
2007-04-19 13:48:01 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-04-19 13:48:01 +00:00
|
|
|
public void visitIsDefined(AstIsDefinedInstruction inst) {
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-04-19 13:48:01 +00:00
|
|
|
}
|
2007-12-10 04:26:21 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-12-10 04:26:21 +00:00
|
|
|
public void visitEcho(AstEchoInstruction inst) {
|
|
|
|
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
protected InterestingVisitor makeInterestingVisitor(CGNode node, int vn) {
|
2007-02-02 17:17:13 +00:00
|
|
|
return new AstInterestingVisitor(vn);
|
|
|
|
}
|
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
@Override
|
2007-06-12 13:43:16 +00:00
|
|
|
public boolean hasNoInterestingUses(CGNode node, int vn, DefUse du) {
|
|
|
|
if (node.getMethod() instanceof AstMethod) {
|
2011-05-02 22:11:27 +00:00
|
|
|
// uses in nested functions are interesting
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
IntSet uses = ((AstIRFactory<?>.AstIR) node.getIR()).lexicalInfo().getAllExposedUses();
|
2008-10-03 20:10:09 +00:00
|
|
|
if (uses.contains(vn)) {
|
2011-05-02 22:11:27 +00:00
|
|
|
return false;
|
2007-06-12 13:43:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.hasNoInterestingUses(node, vn, du);
|
|
|
|
}
|
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-06-01 03:31:35 +00:00
|
|
|
//
|
|
|
|
// IR visitor specialization for Ast-specific IR types
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-06-01 03:31:35 +00:00
|
|
|
|
2015-04-06 01:19:56 +00:00
|
|
|
@Override
|
|
|
|
public ConstraintVisitor makeVisitor(CGNode node) {
|
2007-06-01 03:31:35 +00:00
|
|
|
return new AstConstraintVisitor(this, node);
|
|
|
|
}
|
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
protected static class AstConstraintVisitor extends ConstraintVisitor implements AstInstructionVisitor {
|
2007-07-20 15:19:33 +00:00
|
|
|
|
2012-01-27 20:15:33 +00:00
|
|
|
public AstConstraintVisitor(AstSSAPropagationCallGraphBuilder builder, CGNode node) {
|
2007-06-01 03:31:35 +00:00
|
|
|
super(builder, node);
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
protected AstSSAPropagationCallGraphBuilder getBuilder() {
|
2007-06-06 20:15:48 +00:00
|
|
|
return (AstSSAPropagationCallGraphBuilder) builder;
|
2007-06-01 03:31:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public PointerKey getPointerKeyForObjectCatalog(InstanceKey I) {
|
|
|
|
return ((AstPointerKeyFactory) getBuilder().getPointerKeyFactory()).getPointerKeyForObjectCatalog(I);
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
public Iterator<PointerKey> getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
|
|
|
|
return ((AstPointerKeyFactory) getBuilder().getPointerKeyFactory()).getPointerKeysForReflectedFieldRead(I, F);
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
|
|
|
return ((AstPointerKeyFactory) getBuilder().getPointerKeyFactory()).getPointerKeysForReflectedFieldWrite(I, F);
|
|
|
|
}
|
|
|
|
|
2017-05-11 15:47:19 +00:00
|
|
|
private static void visitLexical(AstLexicalAccess instruction, final LexicalOperator op) {
|
2011-05-23 16:27:07 +00:00
|
|
|
op.doLexicalPointerKeys(false);
|
2012-02-17 20:15:57 +00:00
|
|
|
// I have no idea what the code below does, but commenting it out doesn't
|
|
|
|
// break any regression tests. --MS
|
|
|
|
// if (! checkLexicalInstruction(instruction)) {
|
|
|
|
// system.newSideEffect(op, getPointerKeyForLocal(1));
|
|
|
|
// }
|
2011-05-23 16:27:07 +00:00
|
|
|
}
|
2007-06-01 03:31:35 +00:00
|
|
|
|
2012-02-17 20:15:57 +00:00
|
|
|
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2012-02-17 20:15:57 +00:00
|
|
|
public void visitAstLexicalRead(AstLexicalRead instruction) {
|
|
|
|
visitLexical(instruction, new LexicalOperator((AstCGNode) node, instruction.getAccesses(), true) {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
protected void action(PointerKey lexicalKey, int vn) {
|
|
|
|
PointerKey lval = getPointerKeyForLocal(vn);
|
|
|
|
if (lexicalKey instanceof LocalPointerKey) {
|
|
|
|
CGNode lnode = ((LocalPointerKey) lexicalKey).getNode();
|
|
|
|
int lvn = ((LocalPointerKey) lexicalKey).getValueNumber();
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView lir = getBuilder().getCFAContextInterpreter().getIRView(lnode);
|
2007-06-01 03:31:35 +00:00
|
|
|
SymbolTable lsymtab = lir.getSymbolTable();
|
2017-03-11 18:22:45 +00:00
|
|
|
DefUse ldu = getBuilder().getCFAContextInterpreter().getDU(lnode);
|
|
|
|
// DefUse ldu = getAnalysisCache().getDefUse(lir);
|
2007-06-01 03:31:35 +00:00
|
|
|
if (contentsAreInvariant(lsymtab, ldu, lvn)) {
|
|
|
|
InstanceKey[] ik = getInvariantContents(lsymtab, ldu, lnode, lvn);
|
|
|
|
system.recordImplicitPointsToSet(lexicalKey);
|
|
|
|
for (int i = 0; i < ik.length; i++) {
|
|
|
|
system.findOrCreateIndexForInstanceKey(ik[i]);
|
|
|
|
system.newConstraint(lval, ik[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
system.newConstraint(lval, assignOperator, lexicalKey);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitAstLexicalWrite(AstLexicalWrite instruction) {
|
2012-02-17 20:15:57 +00:00
|
|
|
visitLexical(instruction, new LexicalOperator((AstCGNode) node, instruction.getAccesses(), false) {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
protected void action(PointerKey lexicalKey, int vn) {
|
|
|
|
PointerKey rval = getPointerKeyForLocal(vn);
|
|
|
|
if (contentsAreInvariant(symbolTable, du, vn)) {
|
|
|
|
InstanceKey[] ik = getInvariantContents(vn);
|
|
|
|
system.recordImplicitPointsToSet(rval);
|
|
|
|
for (int i = 0; i < ik.length; i++) {
|
|
|
|
system.findOrCreateIndexForInstanceKey(ik[i]);
|
|
|
|
system.newConstraint(lexicalKey, ik[i]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
system.newConstraint(lexicalKey, assignOperator, rval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitAstGlobalRead(AstGlobalRead instruction) {
|
|
|
|
visitGetInternal(instruction.getDef(), -1, true, instruction.getDeclaredField());
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitAstGlobalWrite(AstGlobalWrite instruction) {
|
|
|
|
visitPutInternal(instruction.getVal(), -1, true, instruction.getDeclaredField());
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitPut(SSAPutInstruction inst) {
|
|
|
|
super.visitPut(inst);
|
|
|
|
|
|
|
|
if (inst.isStatic() || !getBuilder().useObjectCatalog())
|
|
|
|
return;
|
|
|
|
|
2011-05-04 20:42:05 +00:00
|
|
|
// update the object catalog corresponding to the base pointer, adding the
|
|
|
|
// name of the field as a property
|
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
SymbolTable symtab = ir.getSymbolTable();
|
|
|
|
|
|
|
|
int objVn = inst.getRef();
|
2010-09-14 20:29:05 +00:00
|
|
|
String fieldName = null;
|
|
|
|
try {
|
|
|
|
fieldName = inst.getDeclaredField().getName().toUnicodeString();
|
|
|
|
} catch (UTFDataFormatException e) {
|
|
|
|
Assertions.UNREACHABLE();
|
|
|
|
}
|
2007-06-01 03:31:35 +00:00
|
|
|
|
|
|
|
final PointerKey objKey = getPointerKeyForLocal(objVn);
|
|
|
|
|
2012-02-17 20:15:57 +00:00
|
|
|
final InstanceKey[] fieldNameKeys = new InstanceKey[] { getInstanceKeyForConstant(fieldName) };
|
2009-04-30 13:16:52 +00:00
|
|
|
assert fieldNameKeys.length == 1;
|
2007-06-01 03:31:35 +00:00
|
|
|
|
|
|
|
if (contentsAreInvariant(symtab, du, objVn)) {
|
|
|
|
system.recordImplicitPointsToSet(objKey);
|
|
|
|
final InstanceKey[] objKeys = getInvariantContents(objVn);
|
|
|
|
|
|
|
|
for (int i = 0; i < objKeys.length; i++) {
|
2011-05-02 22:11:27 +00:00
|
|
|
if (!getBuilder().isUncataloguedField(objKeys[i].getConcreteType(), fieldName)) {
|
2010-11-02 19:11:58 +00:00
|
|
|
PointerKey objCatalog = getPointerKeyForObjectCatalog(objKeys[i]);
|
|
|
|
if (objCatalog != null) {
|
|
|
|
system.newConstraint(objCatalog, fieldNameKeys[0]);
|
|
|
|
}
|
|
|
|
}
|
2007-06-01 03:31:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2010-11-02 19:11:58 +00:00
|
|
|
final String hack = fieldName;
|
2007-08-31 23:51:10 +00:00
|
|
|
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-08-31 23:51:10 +00:00
|
|
|
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
final IntSetVariable<?> objects = rhs;
|
2007-06-01 03:31:35 +00:00
|
|
|
if (objects.getValue() != null) {
|
|
|
|
objects.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void act(int optr) {
|
|
|
|
InstanceKey object = system.getInstanceKey(optr);
|
2011-05-02 22:11:27 +00:00
|
|
|
if (!getBuilder().isUncataloguedField(object.getConcreteType(), hack)) {
|
2010-11-02 19:11:58 +00:00
|
|
|
PointerKey cat = getPointerKeyForObjectCatalog(object);
|
|
|
|
if (cat != null) {
|
|
|
|
system.newConstraint(cat, fieldNameKeys[0]);
|
|
|
|
}
|
|
|
|
}
|
2007-06-01 03:31:35 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return NOT_CHANGED;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public int hashCode() {
|
|
|
|
return System.identityHashCode(this);
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o == this;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public String toString() {
|
|
|
|
return "field name record: " + objKey;
|
|
|
|
}
|
|
|
|
}, objKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitAssert(AstAssertInstruction instruction) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitEachElementHasNext(EachElementHasNextInstruction inst) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitEachElementGet(EachElementGetInstruction inst) {
|
|
|
|
int lval = inst.getDef(0);
|
|
|
|
final PointerKey lk = getPointerKeyForLocal(lval);
|
|
|
|
|
|
|
|
int rval = inst.getUse(0);
|
|
|
|
final PointerKey rk = getPointerKeyForLocal(rval);
|
|
|
|
|
|
|
|
if (contentsAreInvariant(symbolTable, du, rval)) {
|
|
|
|
InstanceKey objects[] = getInvariantContents(rval);
|
|
|
|
for (int i = 0; i < objects.length; i++) {
|
|
|
|
PointerKey catalog = getPointerKeyForObjectCatalog(objects[i]);
|
|
|
|
system.newConstraint(lk, assignOperator, catalog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
2007-08-31 23:51:10 +00:00
|
|
|
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-08-31 23:51:10 +00:00
|
|
|
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
final IntSetVariable<?> objects = rhs;
|
2007-06-01 03:31:35 +00:00
|
|
|
if (objects.getValue() != null) {
|
|
|
|
objects.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void act(int optr) {
|
|
|
|
InstanceKey object = system.getInstanceKey(optr);
|
|
|
|
PointerKey objCatalog = getPointerKeyForObjectCatalog(object);
|
2010-11-02 19:11:58 +00:00
|
|
|
if (objCatalog != null) {
|
|
|
|
system.newConstraint(lk, assignOperator, objCatalog);
|
|
|
|
}
|
2007-06-01 03:31:35 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return NOT_CHANGED;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public int hashCode() {
|
|
|
|
return System.identityHashCode(this);
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o == this;
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public String toString() {
|
|
|
|
return "get catalog op" + rk;
|
|
|
|
}
|
|
|
|
}, rk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-01 03:31:35 +00:00
|
|
|
public void visitIsDefined(AstIsDefinedInstruction inst) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-12-10 04:26:21 +00:00
|
|
|
public void visitEcho(AstEchoInstruction inst) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-06-06 20:15:48 +00:00
|
|
|
//
|
|
|
|
// lexical scoping handling
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-08-31 23:51:10 +00:00
|
|
|
private abstract class LexicalOperator extends UnaryOperator<PointsToSetVariable> {
|
2011-05-02 22:11:27 +00:00
|
|
|
/**
|
|
|
|
* node in which lexical accesses are performed
|
|
|
|
*/
|
2007-06-06 20:15:48 +00:00
|
|
|
private final AstCGNode node;
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
/**
|
|
|
|
* the lexical accesses to be handled
|
|
|
|
*/
|
2007-06-06 20:15:48 +00:00
|
|
|
private final Access[] accesses;
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
/**
|
2011-05-04 20:42:05 +00:00
|
|
|
* are all the lexical accesses loads? if false, they are all stores
|
2011-05-02 22:11:27 +00:00
|
|
|
*/
|
2007-06-06 20:15:48 +00:00
|
|
|
private final boolean isLoad;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
private LexicalOperator(AstCGNode node, Access[] accesses, boolean isLoad) {
|
|
|
|
this.node = node;
|
|
|
|
this.isLoad = isLoad;
|
|
|
|
this.accesses = accesses;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2011-05-04 20:42:05 +00:00
|
|
|
/**
|
|
|
|
* perform the necessary {@link #action(PointerKey, int)}s for the
|
|
|
|
* accesses. For each access, we determine the possible {@link CGNode}s
|
|
|
|
* corresponding to its definer (see
|
2017-03-23 00:27:33 +00:00
|
|
|
* {@link AstConstraintVisitor#getLexicalDefiners(CGNode, String)}). Handle
|
2013-06-06 23:36:59 +00:00
|
|
|
* using
|
2011-05-04 20:42:05 +00:00
|
|
|
* {@link AstConstraintVisitor#handleRootLexicalReference(String, String, CGNode)}
|
|
|
|
* .
|
|
|
|
*/
|
2011-05-23 16:27:07 +00:00
|
|
|
private void doLexicalPointerKeys(boolean funargsOnly) {
|
2007-06-06 20:15:48 +00:00
|
|
|
for (int i = 0; i < accesses.length; i++) {
|
|
|
|
final String name = accesses[i].variableName;
|
|
|
|
final String definer = accesses[i].variableDefiner;
|
|
|
|
final int vn = accesses[i].valueNumber;
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
if (AstTranslator.DEBUG_LEXICAL)
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("looking up lexical parent " + definer));
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-06 23:36:59 +00:00
|
|
|
Set<CGNode> creators = getLexicalDefiners(node, Pair.make(name, definer));
|
2014-08-07 20:02:48 +00:00
|
|
|
|
|
|
|
System.err.println("definers " + creators.size());
|
|
|
|
|
2013-06-06 23:36:59 +00:00
|
|
|
for (CGNode n : creators) {
|
|
|
|
PointerKey funargKey = handleRootLexicalReference(name, definer, n);
|
|
|
|
action(funargKey, vn);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-08-31 23:51:10 +00:00
|
|
|
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
2011-05-23 16:27:07 +00:00
|
|
|
doLexicalPointerKeys(true);
|
2007-06-06 20:15:48 +00:00
|
|
|
return NOT_CHANGED;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
abstract protected void action(PointerKey lexicalKey, int vn);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public String toString() {
|
|
|
|
return "lexical op";
|
2007-03-12 02:00:43 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (!(o instanceof LexicalOperator)) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
LexicalOperator other = (LexicalOperator) o;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
if (isLoad != other.isLoad) {
|
|
|
|
return false;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
} else if (!node.equals(other.node)) {
|
|
|
|
return false;
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
} else if (accesses.length != other.accesses.length) {
|
|
|
|
return false;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < accesses.length; i++) {
|
|
|
|
if (!accesses[i].equals(other.accesses[i])) {
|
|
|
|
return false;
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < accesses.length; i++) {
|
|
|
|
if (!accesses[i].equals(other.accesses[i])) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public int hashCode() {
|
|
|
|
return node.hashCode() * accesses[0].hashCode() * accesses.length;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2012-02-17 20:15:57 +00:00
|
|
|
private Set<CGNode> getLexicalDefiners(final CGNode opNode, final Pair<String, String> definer) {
|
2007-06-06 20:15:48 +00:00
|
|
|
if (definer == null) {
|
|
|
|
return Collections.singleton(getBuilder().getCallGraph().getFakeRootNode());
|
2013-04-30 03:34:40 +00:00
|
|
|
} else if (getBuilder().sameMethod(opNode, definer.snd)) {
|
2012-02-17 20:15:38 +00:00
|
|
|
// lexical access to a variable declared in opNode itself
|
|
|
|
return Collections.singleton(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
} else {
|
2007-07-11 21:07:32 +00:00
|
|
|
final Set<CGNode> result = HashSetFactory.make();
|
2007-06-06 20:15:48 +00:00
|
|
|
PointerKey F = getBuilder().getPointerKeyForLocal(opNode, 1);
|
|
|
|
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView ir = getBuilder().getCFAContextInterpreter().getIRView(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
SymbolTable symtab = ir.getSymbolTable();
|
2012-03-08 17:34:36 +00:00
|
|
|
DefUse du = getBuilder().getCFAContextInterpreter().getDU(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
if (contentsAreInvariant(symtab, du, 1)) {
|
|
|
|
system.recordImplicitPointsToSet(F);
|
|
|
|
final InstanceKey[] functionKeys = getInvariantContents(symtab, du, opNode, 1);
|
|
|
|
for (int f = 0; f < functionKeys.length; f++) {
|
|
|
|
system.findOrCreateIndexForInstanceKey(functionKeys[f]);
|
|
|
|
ScopeMappingInstanceKey K = (ScopeMappingInstanceKey) functionKeys[f];
|
2011-05-23 16:27:07 +00:00
|
|
|
Iterator<CGNode> x = K.getFunargNodes(definer);
|
|
|
|
while (x.hasNext()) {
|
|
|
|
result.add(x.next());
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PointsToSetVariable FV = system.findOrCreatePointsToSet(F);
|
|
|
|
if (FV.getValue() != null) {
|
|
|
|
FV.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public void act(int ptr) {
|
|
|
|
InstanceKey iKey = system.getInstanceKey(ptr);
|
|
|
|
if (iKey instanceof ScopeMappingInstanceKey) {
|
|
|
|
ScopeMappingInstanceKey K = (ScopeMappingInstanceKey) iKey;
|
2011-05-23 16:27:07 +00:00
|
|
|
Iterator<CGNode> x = K.getFunargNodes(definer);
|
|
|
|
while (x.hasNext()) {
|
|
|
|
result.add(x.next());
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
} else {
|
|
|
|
Assertions.UNREACHABLE("unexpected instance key " + iKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
return result;
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-11 21:07:32 +00:00
|
|
|
private Set<PointerKey> discoveredUpwardFunargs = HashSetFactory.make();
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2011-05-04 20:42:05 +00:00
|
|
|
/**
|
|
|
|
* add constraints that assign the final value of name in definingNode to
|
|
|
|
* the upward funarg (lhs), modeling adding of the state to the closure
|
|
|
|
*/
|
2007-06-06 20:15:48 +00:00
|
|
|
private void addUpwardFunargConstraints(PointerKey lhs, String name, String definer, CGNode definingNode) {
|
|
|
|
discoveredUpwardFunargs.add(lhs);
|
|
|
|
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
LexicalInformation LI = ((AstIRFactory<?>.AstIR) definingNode.getIR()).lexicalInfo();
|
|
|
|
Pair<String, String>[] names = LI.getExposedNames();
|
2007-06-06 20:15:48 +00:00
|
|
|
for (int i = 0; i < names.length; i++) {
|
|
|
|
if (name.equals(names[i].fst) && definer.equals(names[i].snd)) {
|
|
|
|
int vn = LI.getExitExposedUses()[i];
|
|
|
|
if (vn > 0) {
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView ir = getBuilder().getCFAContextInterpreter().getIRView(definingNode);
|
2007-07-06 22:09:29 +00:00
|
|
|
DefUse du = getBuilder().getCFAContextInterpreter().getDU(definingNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
SymbolTable st = ir.getSymbolTable();
|
|
|
|
|
|
|
|
PointerKey rhs = getBuilder().getPointerKeyForLocal(definingNode, vn);
|
|
|
|
|
|
|
|
if (contentsAreInvariant(st, du, vn)) {
|
|
|
|
system.recordImplicitPointsToSet(rhs);
|
|
|
|
final InstanceKey[] objs = getInvariantContents(st, du, definingNode, vn);
|
|
|
|
for (int f = 0; f < objs.length; f++) {
|
|
|
|
system.findOrCreateIndexForInstanceKey(objs[f]);
|
|
|
|
system.newConstraint(lhs, objs[f]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
system.newConstraint(lhs, assignOperator, rhs);
|
|
|
|
}
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
return;
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
Assertions.UNREACHABLE();
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2011-05-04 20:42:05 +00:00
|
|
|
/**
|
|
|
|
* handle a lexical reference where we found no parent call graph node
|
|
|
|
* defining the name; it's either a global or an upward funarg
|
|
|
|
*/
|
2007-06-06 20:15:48 +00:00
|
|
|
private PointerKey handleRootLexicalReference(String name, String definer, final CGNode definingNode) {
|
|
|
|
// global variable
|
|
|
|
if (definer == null) {
|
|
|
|
return new AstGlobalPointerKey(name);
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
// upward funarg
|
|
|
|
} else {
|
|
|
|
class UpwardFunargPointerKey extends AstGlobalPointerKey {
|
|
|
|
UpwardFunargPointerKey(String name) {
|
|
|
|
super(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public CGNode getDefiningNode() {
|
|
|
|
return definingNode;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public boolean equals(Object x) {
|
2011-05-02 22:11:27 +00:00
|
|
|
return (x instanceof UpwardFunargPointerKey)
|
|
|
|
&& super.equals(x)
|
|
|
|
&& (definingNode == null ? definingNode == ((UpwardFunargPointerKey) x).getDefiningNode() : definingNode
|
|
|
|
.equals(((UpwardFunargPointerKey) x).getDefiningNode()));
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public int hashCode() {
|
2011-05-02 22:11:27 +00:00
|
|
|
return super.hashCode() * ((definingNode == null) ? 17 : definingNode.hashCode());
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public String toString() {
|
|
|
|
return "[upward:" + getName() + ":" + definingNode + "]";
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
PointerKey result = new UpwardFunargPointerKey(name);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2011-05-02 22:11:27 +00:00
|
|
|
if (!discoveredUpwardFunargs.contains(result) && definingNode != null) {
|
2007-06-06 20:15:48 +00:00
|
|
|
addUpwardFunargConstraints(result, name, definer, definingNode);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
return result;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2013-06-06 23:18:16 +00:00
|
|
|
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-06-06 20:15:48 +00:00
|
|
|
//
|
|
|
|
// property manipulation handling
|
|
|
|
//
|
2007-07-20 15:19:33 +00:00
|
|
|
// /////////////////////////////////////////////////////////////////////////
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2012-03-01 02:45:51 +00:00
|
|
|
protected interface ReflectedFieldAction {
|
2007-06-28 14:30:15 +00:00
|
|
|
void action(AbstractFieldPointerKey fieldKey);
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-28 14:30:15 +00:00
|
|
|
void dump(AbstractFieldPointerKey fieldKey, boolean constObj, boolean constProp);
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-07-20 15:19:33 +00:00
|
|
|
private void newFieldOperation(CGNode opNode, final int objVn, final int fieldsVn, final boolean isLoadOperation,
|
|
|
|
final ReflectedFieldAction action) {
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView ir = getBuilder().getCFAContextInterpreter().getIRView(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
SymbolTable symtab = ir.getSymbolTable();
|
2007-07-06 22:09:29 +00:00
|
|
|
DefUse du = getBuilder().getCFAContextInterpreter().getDU(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
PointerKey objKey = getBuilder().getPointerKeyForLocal(opNode, objVn);
|
|
|
|
final PointerKey fieldKey = getBuilder().getPointerKeyForLocal(opNode, fieldsVn);
|
|
|
|
|
|
|
|
// log field access
|
|
|
|
if (DEBUG_PROPERTIES) {
|
|
|
|
if (isLoadOperation)
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print(("adding read of " + objKey + "." + fieldKey + ":"));
|
2007-06-06 20:15:48 +00:00
|
|
|
else
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print(("adding write of " + objKey + "." + fieldKey + ":"));
|
2007-06-06 20:15:48 +00:00
|
|
|
|
|
|
|
if (contentsAreInvariant(symtab, du, objVn)) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print(" constant obj:");
|
2007-06-06 20:15:48 +00:00
|
|
|
InstanceKey[] x = getInvariantContents(symtab, du, opNode, objVn);
|
|
|
|
for (int i = 0; i < x.length; i++) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print((x[i].toString() + " "));
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
} else {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print((" obj:" + system.findOrCreatePointsToSet(objKey)));
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (contentsAreInvariant(symtab, du, fieldsVn)) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print(" constant prop:");
|
2007-06-06 20:15:48 +00:00
|
|
|
InstanceKey[] x = getInvariantContents(symtab, du, opNode, fieldsVn);
|
|
|
|
for (int i = 0; i < x.length; i++) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print((x[i].toString() + " "));
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
} else {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print((" props:" + system.findOrCreatePointsToSet(fieldKey)));
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.print("\n");
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// make sure instance keys get mapped for PointerAnalysisImpl
|
2007-02-02 17:17:13 +00:00
|
|
|
if (contentsAreInvariant(symtab, du, objVn)) {
|
2007-06-01 03:31:35 +00:00
|
|
|
InstanceKey[] x = getInvariantContents(symtab, du, opNode, objVn);
|
2007-02-09 15:33:45 +00:00
|
|
|
for (int i = 0; i < x.length; i++) {
|
2007-06-06 20:15:48 +00:00
|
|
|
system.findOrCreateIndexForInstanceKey(x[i]);
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
if (contentsAreInvariant(symtab, du, fieldsVn)) {
|
2007-06-01 03:31:35 +00:00
|
|
|
InstanceKey[] x = getInvariantContents(symtab, du, opNode, fieldsVn);
|
2007-02-09 15:33:45 +00:00
|
|
|
for (int i = 0; i < x.length; i++) {
|
2007-06-06 20:15:48 +00:00
|
|
|
system.findOrCreateIndexForInstanceKey(x[i]);
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
// process field access
|
|
|
|
if (contentsAreInvariant(symtab, du, objVn)) {
|
|
|
|
system.recordImplicitPointsToSet(objKey);
|
|
|
|
final InstanceKey[] objKeys = getInvariantContents(symtab, du, opNode, objVn);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
if (contentsAreInvariant(symtab, du, fieldsVn)) {
|
|
|
|
system.recordImplicitPointsToSet(fieldKey);
|
|
|
|
InstanceKey[] fieldsKeys = getInvariantContents(symtab, du, opNode, fieldsVn);
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
newFieldOperationObjectAndFieldConstant(isLoadOperation, action, objKeys, fieldsKeys);
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
} else {
|
2011-05-23 16:27:07 +00:00
|
|
|
newFieldOperationOnlyObjectConstant(isLoadOperation, action, fieldKey, objKeys);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (contentsAreInvariant(symtab, du, fieldsVn)) {
|
|
|
|
system.recordImplicitPointsToSet(fieldKey);
|
|
|
|
final InstanceKey[] fieldsKeys = getInvariantContents(symtab, du, opNode, fieldsVn);
|
|
|
|
|
|
|
|
newFieldOperationOnlyFieldConstant(isLoadOperation, action, objKey, fieldsKeys);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
newFieldFullOperation(isLoadOperation, action, objKey, fieldKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DEBUG_PROPERTIES) {
|
|
|
|
System.err.println("finished\n");
|
|
|
|
}
|
|
|
|
}
|
2012-02-17 20:15:57 +00:00
|
|
|
|
|
|
|
protected void newFieldOperationFieldConstant(CGNode opNode, final boolean isLoadOperation, final ReflectedFieldAction action,
|
|
|
|
final int objVn, final InstanceKey[] fieldsKeys) {
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView ir = getBuilder().getCFAContextInterpreter().getIRView(opNode);
|
2011-05-23 16:27:07 +00:00
|
|
|
SymbolTable symtab = ir.getSymbolTable();
|
|
|
|
DefUse du = getBuilder().getCFAContextInterpreter().getDU(opNode);
|
|
|
|
PointerKey objKey = getBuilder().getPointerKeyForLocal(opNode, objVn);
|
|
|
|
|
|
|
|
if (contentsAreInvariant(symtab, du, objVn)) {
|
|
|
|
system.recordImplicitPointsToSet(objKey);
|
|
|
|
InstanceKey[] objectKeys = getInvariantContents(symtab, du, opNode, objVn);
|
|
|
|
|
|
|
|
newFieldOperationObjectAndFieldConstant(isLoadOperation, action, objectKeys, fieldsKeys);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
newFieldOperationOnlyFieldConstant(isLoadOperation, action, objKey, fieldsKeys);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2012-03-01 02:45:51 +00:00
|
|
|
protected void newFieldFullOperation(final boolean isLoadOperation, final ReflectedFieldAction action, PointerKey objKey,
|
2011-05-23 16:27:07 +00:00
|
|
|
final PointerKey fieldKey) {
|
|
|
|
system.newSideEffect(new AbstractOperator<PointsToSetVariable>() {
|
2011-07-01 13:40:26 +00:00
|
|
|
private final MutableIntSet doneReceiver = IntSetUtil.make();
|
|
|
|
private final MutableIntSet doneField = IntSetUtil.make();
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public byte evaluate(PointsToSetVariable lhs, final PointsToSetVariable[] rhs) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
final IntSetVariable<?> receivers = rhs[0];
|
|
|
|
final IntSetVariable<?> fields = rhs[1];
|
2011-05-23 16:27:07 +00:00
|
|
|
if (receivers.getValue() != null && fields.getValue() != null) {
|
|
|
|
receivers.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-07-01 13:40:26 +00:00
|
|
|
public void act(final int rptr) {
|
2011-05-23 16:27:07 +00:00
|
|
|
final InstanceKey receiver = system.getInstanceKey(rptr);
|
|
|
|
|
|
|
|
if (!isLoadOperation) {
|
|
|
|
PointerKey cat = getPointerKeyForObjectCatalog(receiver);
|
|
|
|
if (cat != null) {
|
|
|
|
system.newConstraint(cat, assignOperator, fieldKey);
|
|
|
|
}
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
fields.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-06 20:15:48 +00:00
|
|
|
public void act(int fptr) {
|
2011-07-01 13:40:26 +00:00
|
|
|
if (!doneField.contains(fptr) || !doneReceiver.contains(rptr)) {
|
|
|
|
InstanceKey field = system.getInstanceKey(fptr);
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<PointerKey> keys = isLoadOperation ? getPointerKeysForReflectedFieldRead(receiver, field)
|
2012-02-17 20:15:57 +00:00
|
|
|
: getPointerKeysForReflectedFieldWrite(receiver, field); keys.hasNext();) {
|
2011-07-01 13:40:26 +00:00
|
|
|
AbstractFieldPointerKey key = (AbstractFieldPointerKey) keys.next();
|
|
|
|
if (DEBUG_PROPERTIES)
|
|
|
|
action.dump(key, false, false);
|
|
|
|
action.action(key);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
});
|
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
});
|
2011-07-01 13:40:26 +00:00
|
|
|
doneReceiver.addAll(receivers.getValue());
|
|
|
|
doneField.addAll(fields.getValue());
|
2011-05-23 16:27:07 +00:00
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
return NOT_CHANGED;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public String toString() {
|
|
|
|
return "field op";
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o == this;
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public int hashCode() {
|
|
|
|
return System.identityHashCode(this);
|
|
|
|
}
|
|
|
|
}, objKey, fieldKey);
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2012-03-01 02:45:51 +00:00
|
|
|
protected void newFieldOperationOnlyFieldConstant(final boolean isLoadOperation, final ReflectedFieldAction action,
|
2012-02-17 20:15:57 +00:00
|
|
|
final PointerKey objKey, final InstanceKey[] fieldsKeys) {
|
2011-05-23 16:27:07 +00:00
|
|
|
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
final IntSetVariable<?> objects = rhs;
|
2011-05-23 16:27:07 +00:00
|
|
|
if (objects.getValue() != null) {
|
|
|
|
objects.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public void act(int optr) {
|
|
|
|
InstanceKey object = system.getInstanceKey(optr);
|
|
|
|
PointerKey objCatalog = getPointerKeyForObjectCatalog(object);
|
|
|
|
for (int f = 0; f < fieldsKeys.length; f++) {
|
|
|
|
if (isLoadOperation) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<PointerKey> keys = getPointerKeysForReflectedFieldRead(object, fieldsKeys[f]); keys.hasNext();) {
|
2011-05-23 16:27:07 +00:00
|
|
|
AbstractFieldPointerKey key = (AbstractFieldPointerKey) keys.next();
|
|
|
|
if (DEBUG_PROPERTIES)
|
|
|
|
action.dump(key, true, false);
|
|
|
|
action.action(key);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (objCatalog != null) {
|
|
|
|
system.newConstraint(objCatalog, fieldsKeys[f]);
|
|
|
|
}
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<PointerKey> keys = getPointerKeysForReflectedFieldWrite(object, fieldsKeys[f]); keys.hasNext();) {
|
2011-05-23 16:27:07 +00:00
|
|
|
AbstractFieldPointerKey key = (AbstractFieldPointerKey) keys.next();
|
|
|
|
if (DEBUG_PROPERTIES)
|
|
|
|
action.dump(key, true, false);
|
|
|
|
action.action(key);
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return NOT_CHANGED;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public int hashCode() {
|
|
|
|
return System.identityHashCode(this);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o == this;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public String toString() {
|
|
|
|
return "field op" + objKey;
|
|
|
|
}
|
|
|
|
}, objKey);
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2012-03-01 02:45:51 +00:00
|
|
|
protected void newFieldOperationOnlyObjectConstant(final boolean isLoadOperation, final ReflectedFieldAction action,
|
2012-02-17 20:15:57 +00:00
|
|
|
final PointerKey fieldKey, final InstanceKey[] objKeys) {
|
2011-05-23 16:27:07 +00:00
|
|
|
if (!isLoadOperation) {
|
|
|
|
for (int o = 0; o < objKeys.length; o++) {
|
|
|
|
PointerKey objCatalog = getPointerKeyForObjectCatalog(objKeys[o]);
|
|
|
|
if (objCatalog != null) {
|
|
|
|
system.newConstraint(objCatalog, assignOperator, fieldKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
final IntSetVariable<?> fields = rhs;
|
2011-05-23 16:27:07 +00:00
|
|
|
if (fields.getValue() != null) {
|
|
|
|
fields.getValue().foreach(new IntSetAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public void act(int fptr) {
|
|
|
|
InstanceKey field = system.getInstanceKey(fptr);
|
|
|
|
for (int o = 0; o < objKeys.length; o++) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<PointerKey> keys = isLoadOperation ? getPointerKeysForReflectedFieldRead(objKeys[o], field)
|
2011-05-23 16:27:07 +00:00
|
|
|
: getPointerKeysForReflectedFieldWrite(objKeys[o], field); keys.hasNext();) {
|
|
|
|
AbstractFieldPointerKey key = (AbstractFieldPointerKey) keys.next();
|
|
|
|
if (DEBUG_PROPERTIES)
|
|
|
|
action.dump(key, false, true);
|
|
|
|
action.action(key);
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return NOT_CHANGED;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public int hashCode() {
|
|
|
|
return System.identityHashCode(this);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o == this;
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public String toString() {
|
|
|
|
return "field op" + fieldKey;
|
|
|
|
}
|
|
|
|
}, fieldKey);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2012-03-01 02:45:51 +00:00
|
|
|
protected void newFieldOperationObjectAndFieldConstant(final boolean isLoadOperation, final ReflectedFieldAction action,
|
2011-05-23 16:27:07 +00:00
|
|
|
final InstanceKey[] objKeys, InstanceKey[] fieldsKeys) {
|
|
|
|
for (int o = 0; o < objKeys.length; o++) {
|
|
|
|
PointerKey objCatalog = getPointerKeyForObjectCatalog(objKeys[o]);
|
|
|
|
for (int f = 0; f < fieldsKeys.length; f++) {
|
|
|
|
if (isLoadOperation) {
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<PointerKey> keys = getPointerKeysForReflectedFieldRead(objKeys[o], fieldsKeys[f]); keys.hasNext();) {
|
2011-05-23 16:27:07 +00:00
|
|
|
AbstractFieldPointerKey key = (AbstractFieldPointerKey) keys.next();
|
|
|
|
if (DEBUG_PROPERTIES)
|
|
|
|
action.dump(key, true, true);
|
|
|
|
action.action(key);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (objCatalog != null) {
|
|
|
|
system.newConstraint(objCatalog, fieldsKeys[f]);
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
Fix nearly all Eclipse warnings about using raw types
Along the way, I also converted many "for (;;)" loops into modern
"for (:)" loops. I didn't systematically look for all opportunities
to do this, though. I merely made this change where I was already
converting raw Iterator uses into modern Iterator<...> uses.
Better use of generics also allowed many casts to become statically
redundant. I have removed all such redundant casts.
Only three raw-types warnings remain after this batch of fixes. All
three involve raw uses of CallGraphBuilder. I've tried to fix these
too, but it quickly snowballs into a cascade of changes that may or
may not eventually reach a statically-type-save fixed point. I may
give these last few problem areas another go in the future. For now,
though, the hundreds of other fixes seem worth keeping even if there
are a few stragglers.
This commit may change some public APIs, but only by making weaker
type signatures stronger by replacing raw types with generic types.
For example, we may change something like "Set" into "Set<String>",
but we're not adding new arguments, changing any
underlying (post-generics-erasure) types, etc.
2017-07-09 18:38:35 +00:00
|
|
|
for (Iterator<PointerKey> keys = getPointerKeysForReflectedFieldWrite(objKeys[o], fieldsKeys[f]); keys.hasNext();) {
|
2011-05-23 16:27:07 +00:00
|
|
|
AbstractFieldPointerKey key = (AbstractFieldPointerKey) keys.next();
|
|
|
|
if (DEBUG_PROPERTIES)
|
|
|
|
action.dump(key, true, true);
|
|
|
|
action.action(key);
|
|
|
|
}
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
|
|
|
|
2011-04-27 13:58:56 +00:00
|
|
|
public void newFieldWrite(CGNode opNode, int objVn, int fieldsVn, int rhsVn) {
|
2017-03-11 18:22:45 +00:00
|
|
|
IRView ir = getBuilder().getCFAContextInterpreter().getIRView(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
SymbolTable symtab = ir.getSymbolTable();
|
2007-07-06 22:09:29 +00:00
|
|
|
DefUse du = getBuilder().getCFAContextInterpreter().getDU(opNode);
|
2007-06-06 20:15:48 +00:00
|
|
|
PointerKey rhsKey = getBuilder().getPointerKeyForLocal(opNode, rhsVn);
|
|
|
|
if (contentsAreInvariant(symtab, du, rhsVn)) {
|
|
|
|
system.recordImplicitPointsToSet(rhsKey);
|
|
|
|
newFieldWrite(opNode, objVn, fieldsVn, getInvariantContents(symtab, du, opNode, rhsVn));
|
|
|
|
} else {
|
|
|
|
newFieldWrite(opNode, objVn, fieldsVn, rhsKey);
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
private final class ConstantWriter implements ReflectedFieldAction {
|
|
|
|
private final InstanceKey[] rhsFixedValues;
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
private ConstantWriter(InstanceKey[] rhsFixedValues) {
|
|
|
|
this.rhsFixedValues = rhsFixedValues;
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public void dump(AbstractFieldPointerKey fieldKey, boolean constObj, boolean constProp) {
|
|
|
|
System.err.println(("writing fixed rvals to " + fieldKey + " " + constObj + ", " + constProp));
|
|
|
|
for (int i = 0; i < rhsFixedValues.length; i++) {
|
|
|
|
System.err.println(("writing " + rhsFixedValues[i]));
|
|
|
|
}
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public void action(AbstractFieldPointerKey fieldKey) {
|
|
|
|
if (!representsNullType(fieldKey.getInstanceKey())) {
|
|
|
|
for (int i = 0; i < rhsFixedValues.length; i++) {
|
|
|
|
system.findOrCreateIndexForInstanceKey(rhsFixedValues[i]);
|
|
|
|
system.newConstraint(fieldKey, rhsFixedValues[i]);
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
public void newFieldWrite(CGNode opNode, int objVn, int fieldsVn, final InstanceKey[] rhsFixedValues) {
|
|
|
|
newFieldOperation(opNode, objVn, fieldsVn, false, new ConstantWriter(rhsFixedValues));
|
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
public void newFieldWrite(CGNode opNode, int objVn, InstanceKey[] fieldKeys, final InstanceKey[] rhsValues) {
|
|
|
|
newFieldOperationFieldConstant(opNode, false, new ConstantWriter(rhsValues), objVn, fieldKeys);
|
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
private final class NormalWriter implements ReflectedFieldAction {
|
|
|
|
private final PointerKey rhs;
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
private NormalWriter(PointerKey rhs) {
|
|
|
|
this.rhs = rhs;
|
|
|
|
}
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public void dump(AbstractFieldPointerKey fieldKey, boolean constObj, boolean constProp) {
|
|
|
|
System.err.println(("write " + rhs + " to " + fieldKey + " " + constObj + ", " + constProp));
|
|
|
|
}
|
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2011-05-23 16:27:07 +00:00
|
|
|
public void action(AbstractFieldPointerKey fieldKey) {
|
|
|
|
if (!representsNullType(fieldKey.getInstanceKey())) {
|
|
|
|
system.newConstraint(fieldKey, assignOperator, rhs);
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
2011-05-23 16:27:07 +00:00
|
|
|
}
|
2017-07-12 23:54:57 +00:00
|
|
|
}
|
2012-02-17 20:15:57 +00:00
|
|
|
|
2011-05-23 16:27:07 +00:00
|
|
|
public void newFieldWrite(CGNode opNode, int objVn, int fieldsVn, final PointerKey rhs) {
|
|
|
|
newFieldOperation(opNode, objVn, fieldsVn, false, new NormalWriter(rhs));
|
|
|
|
}
|
|
|
|
|
|
|
|
public void newFieldWrite(CGNode opNode, int objVn, InstanceKey[] fieldKeys, final PointerKey rhs) {
|
|
|
|
newFieldOperationFieldConstant(opNode, false, new NormalWriter(rhs), objVn, fieldKeys);
|
2007-02-09 15:33:45 +00:00
|
|
|
}
|
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
protected void newFieldRead(CGNode opNode, int objVn, int fieldsVn, int lhsVn) {
|
|
|
|
newFieldRead(opNode, objVn, fieldsVn, getBuilder().getPointerKeyForLocal(opNode, lhsVn));
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
|
2007-06-06 20:15:48 +00:00
|
|
|
protected void newFieldRead(CGNode opNode, int objVn, int fieldsVn, final PointerKey lhs) {
|
|
|
|
newFieldOperation(opNode, objVn, fieldsVn, true, new ReflectedFieldAction() {
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-28 14:30:15 +00:00
|
|
|
public void dump(AbstractFieldPointerKey fieldKey, boolean constObj, boolean constProp) {
|
2009-04-09 20:31:14 +00:00
|
|
|
System.err.println(("read " + lhs + " from " + fieldKey + " " + constObj + ", " + constProp));
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
2007-02-09 15:33:45 +00:00
|
|
|
|
2013-06-25 15:57:37 +00:00
|
|
|
@Override
|
2007-06-28 14:30:15 +00:00
|
|
|
public void action(AbstractFieldPointerKey fieldKey) {
|
2007-07-20 15:19:33 +00:00
|
|
|
if (!representsNullType(fieldKey.getInstanceKey())) {
|
|
|
|
system.newConstraint(lhs, assignOperator, fieldKey);
|
2014-10-15 07:01:38 +00:00
|
|
|
AbstractFieldPointerKey unknown = getBuilder().fieldKeyForUnknownWrites(fieldKey);
|
|
|
|
if (unknown != null) {
|
|
|
|
system.newConstraint(lhs, assignOperator, unknown);
|
|
|
|
}
|
2007-07-20 15:19:33 +00:00
|
|
|
}
|
2007-06-06 20:15:48 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2007-02-02 17:17:13 +00:00
|
|
|
}
|
2013-04-30 03:34:40 +00:00
|
|
|
|
2014-10-15 07:01:38 +00:00
|
|
|
/**
|
|
|
|
* If the given fieldKey represents a concrete field, return the corresponding field key that
|
|
|
|
* represents all writes to unknown fields that could potentially alias fieldKey
|
|
|
|
*/
|
|
|
|
protected abstract AbstractFieldPointerKey fieldKeyForUnknownWrites(AbstractFieldPointerKey fieldKey);
|
|
|
|
|
2013-04-30 03:34:40 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Is definingMethod the same as the method represented by opNode? We need this since the names for
|
|
|
|
* methods in some languages don't map in the straightforward way to the CGNode
|
|
|
|
*/
|
|
|
|
protected abstract boolean sameMethod(final CGNode opNode, final String definingMethod);
|
|
|
|
|
2007-06-01 03:31:35 +00:00
|
|
|
}
|