enhancements to handling of lexical scoping
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@3109 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
16c7e503b2
commit
309a9b6d72
|
@ -10,6 +10,7 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingKeysContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
|
@ -39,6 +40,8 @@ public class JSZeroOrOneXCFABuilder extends JSCFABuilder {
|
|||
|
||||
ContextSelector def = new DefaultContextSelector();
|
||||
ContextSelector contextSelector = appContextSelector == null ? def : new DelegatingContextSelector(appContextSelector, def);
|
||||
contextSelector = new ScopeMappingKeysContextSelector(contextSelector);
|
||||
contextSelector = new JavaScriptConstructorContextSelector(contextSelector);
|
||||
if (doOneCFA) {
|
||||
contextSelector = new nCFAContextSelector(1, contextSelector);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
private final Map<Object, IMethod> constructors = HashMapFactory.make();
|
||||
|
||||
private class JavaScriptConstructor extends JavaScriptSummarizedFunction {
|
||||
class JavaScriptConstructor extends JavaScriptSummarizedFunction {
|
||||
private final String toStringExtra;
|
||||
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass, String toStringExtra) {
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.ibm.wala.cast.js.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingKeysContextSelector.ScopeMappingContext;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptConstructTargetSelector.JavaScriptConstructor;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
|
||||
public class JavaScriptConstructorContextSelector implements ContextSelector {
|
||||
private final ContextSelector base;
|
||||
|
||||
public JavaScriptConstructorContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
|
||||
if (caller.getMethod().getDeclaringClass().getName().toString().indexOf("f/ff") != -1) {
|
||||
System.err.println("got hete");
|
||||
}
|
||||
|
||||
if (callee instanceof JavaScriptConstructor && caller.getContext() instanceof ScopeMappingContext) {
|
||||
return caller.getContext();
|
||||
} else {
|
||||
return base.getCalleeTarget(caller, site, callee, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.cast.js.ipa.callgraph;
|
|||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader.JavaScriptMethodObject;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalParent;
|
||||
import com.ibm.wala.cast.types.AstMethodReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Collections;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.AstTranslator.AstLexicalInformation;
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.loader.AstClass;
|
||||
|
@ -186,7 +187,7 @@ public class JavaScriptLoader extends CAstAbstractLoader {
|
|||
public class JavaScriptMethodObject extends AstMethod {
|
||||
|
||||
JavaScriptMethodObject(JavaScriptCodeBody cls, AbstractCFG cfg, SymbolTable symtab, boolean hasCatchBlock,
|
||||
TypeReference[][] caughtTypes, LexicalInformation lexicalInfo, DebuggingInformation debugInfo) {
|
||||
TypeReference[][] caughtTypes, AstLexicalInformation lexicalInfo, DebuggingInformation debugInfo) {
|
||||
super(cls, functionQualifiers, cfg, symtab, AstMethodReference.fnReference(cls.getReference()), hasCatchBlock, caughtTypes,
|
||||
lexicalInfo, debugInfo);
|
||||
}
|
||||
|
@ -204,10 +205,10 @@ public class JavaScriptLoader extends CAstAbstractLoader {
|
|||
}
|
||||
|
||||
public LexicalParent[] getParents() {
|
||||
if (lexicalInfo == null)
|
||||
if (lexicalInfo() == null)
|
||||
return new LexicalParent[0];
|
||||
|
||||
final String[] parents = lexicalInfo.getScopingParents();
|
||||
final String[] parents = lexicalInfo().getScopingParents();
|
||||
|
||||
if (parents == null)
|
||||
return new LexicalParent[0];
|
||||
|
@ -270,7 +271,7 @@ public class JavaScriptLoader extends CAstAbstractLoader {
|
|||
}
|
||||
|
||||
public IMethod defineCodeBodyCode(String clsName, AbstractCFG cfg, SymbolTable symtab, boolean hasCatchBlock,
|
||||
TypeReference[][] caughtTypes, LexicalInformation lexicalInfo, DebuggingInformation debugInfo) {
|
||||
TypeReference[][] caughtTypes, AstLexicalInformation lexicalInfo, DebuggingInformation debugInfo) {
|
||||
JavaScriptCodeBody C = (JavaScriptCodeBody) lookupClass(clsName, cha);
|
||||
Assertions._assert(C != null, clsName);
|
||||
return C.setCodeBody(new JavaScriptMethodObject(C, cfg, symtab, hasCatchBlock, caughtTypes, lexicalInfo, debugInfo));
|
||||
|
|
|
@ -80,6 +80,8 @@ public class AstCallGraph extends ExplicitCallGraph {
|
|||
protected class AstCGNode extends ExplicitNode {
|
||||
private Set<Function<Object, Object>> callbacks;
|
||||
|
||||
private boolean lexicalScopingChanges = false;
|
||||
|
||||
private AstCGNode(IMethod method, Context context) {
|
||||
super(method, context);
|
||||
}
|
||||
|
@ -137,6 +139,10 @@ public class AstCallGraph extends ExplicitCallGraph {
|
|||
}
|
||||
}
|
||||
|
||||
public void setLexicalScopingChanges() {
|
||||
lexicalScopingChanges = true;
|
||||
}
|
||||
|
||||
public boolean addTarget(CallSiteReference site, CGNode node) {
|
||||
if (super.addTarget(site, node)) {
|
||||
if (((AstCGNode) node).callbacks != null) {
|
||||
|
|
|
@ -108,6 +108,8 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
SSAContextInterpreter c = new DefaultSSAInterpreter(options, getAnalysisCache());
|
||||
c = new DelegatingSSAContextInterpreter(new AstContextInsensitiveSSAContextInterpreter(options, getAnalysisCache()), c);
|
||||
|
||||
c = new DelegatingSSAContextInterpreter(new LexicalScopingSSAContextInterpreter(options, getAnalysisCache()), c);
|
||||
|
||||
c = new DelegatingSSAContextInterpreter(ReflectionContextInterpreter.createReflectionContextInterpreter(cha, options, getAnalysisCache(), reflect), c);
|
||||
|
||||
if (appContextInterpreter == null)
|
||||
|
@ -243,7 +245,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
|
||||
public boolean hasNoInterestingUses(CGNode node, int vn, DefUse du) {
|
||||
if (node.getMethod() instanceof AstMethod) {
|
||||
IntSet uses = ((AstMethod) node.getMethod()).lexicalInfo.getAllExposedUses();
|
||||
IntSet uses = ((AstIR) node.getIR()).lexicalInfo().getAllExposedUses();
|
||||
if (uses.contains(vn)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -663,7 +665,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
private void addUpwardFunargConstraints(PointerKey lhs, String name, String definer, CGNode definingNode) {
|
||||
discoveredUpwardFunargs.add(lhs);
|
||||
|
||||
LexicalInformation LI = ((AstMethod) definingNode.getMethod()).lexicalInfo;
|
||||
LexicalInformation LI = ((AstIR) definingNode.getIR()).lexicalInfo();
|
||||
Pair[] names = LI.getExposedNames();
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
if (name.equals(names[i].fst) && definer.equals(names[i].snd)) {
|
||||
|
@ -712,11 +714,13 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
|
||||
public boolean equals(Object x) {
|
||||
return (x instanceof UpwardFunargPointerKey) && super.equals(x)
|
||||
&& definingNode.equals(((UpwardFunargPointerKey) x).getDefiningNode());
|
||||
&& (definingNode == null?
|
||||
definingNode == ((UpwardFunargPointerKey) x).getDefiningNode():
|
||||
definingNode.equals(((UpwardFunargPointerKey) x).getDefiningNode()));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return super.hashCode() * definingNode.hashCode();
|
||||
return super.hashCode() * ((definingNode == null)? 17: definingNode.hashCode());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -726,7 +730,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
|
||||
PointerKey result = new UpwardFunargPointerKey(name);
|
||||
|
||||
if (!discoveredUpwardFunargs.contains(result)) {
|
||||
if (!discoveredUpwardFunargs.contains(result) && definingNode != null) {
|
||||
addUpwardFunargConstraints(result, name, definer, definingNode);
|
||||
}
|
||||
|
||||
|
@ -741,9 +745,9 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
}
|
||||
|
||||
else if (M instanceof AstMethod) {
|
||||
AstIR ir = (AstIR) getBuilder().getCFAContextInterpreter().getIR(n);
|
||||
AstIR ir = (AstIR) n.getIR();
|
||||
int pc = callSite.getProgramCounter();
|
||||
LexicalInformation L = ((AstMethod) M).lexicalInfo;
|
||||
LexicalInformation L = ((AstIR) n.getIR()).lexicalInfo();
|
||||
|
||||
// some people have no lexical uses at all
|
||||
if (L == null) {
|
||||
|
@ -776,6 +780,8 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
|
||||
SSAConversion.copyUse(ir, pc, -i - 1, pc, I.getNumberOfUses() - 1);
|
||||
|
||||
((AstCallGraph.AstCGNode)n).setLexicalScopingChanges();
|
||||
|
||||
return getBuilder().getPointerKeyForLocal(n, values[i]);
|
||||
}
|
||||
}
|
||||
|
@ -796,13 +802,13 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
|
||||
else if (M instanceof AstMethod) {
|
||||
AstMethod AstM = (AstMethod) M;
|
||||
LexicalInformation L = AstM.lexicalInfo;
|
||||
AstIR ir = (AstIR) n.getIR();
|
||||
LexicalInformation L = ir.lexicalInfo();
|
||||
|
||||
// some people have no lexical uses at all
|
||||
if (L == null)
|
||||
return null;
|
||||
|
||||
AstIR ir = (AstIR) getBuilder().getCFAContextInterpreter().getIR(n);
|
||||
int pc = callSite.getProgramCounter();
|
||||
AbstractLexicalInvoke I = (AbstractLexicalInvoke) ir.getInstructions()[pc];
|
||||
|
||||
|
@ -843,7 +849,8 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
|
||||
// now redo analysis
|
||||
// TODO: only values[i] uses need to be re-done.
|
||||
AstM.lexicalInfo.handleAlteration();
|
||||
ir.lexicalInfo().handleAlteration();
|
||||
((AstCallGraph.AstCGNode)n).setLexicalScopingChanges();
|
||||
getAnalysisCache().getSSACache().invalidateDU(M, n.getContext());
|
||||
// addConstraintsFromChangedNode(n);
|
||||
getBuilder().markChanged(n);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingKeysContextSelector.ScopeMappingContext;
|
||||
import com.ibm.wala.cast.loader.AstMethod;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.ISSABasicBlock;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
|
||||
public class LexicalScopingSSAContextInterpreter extends AstContextInsensitiveSSAContextInterpreter implements SSAContextInterpreter {
|
||||
|
||||
public LexicalScopingSSAContextInterpreter(AnalysisOptions options, AnalysisCache cache) {
|
||||
super(options, cache);
|
||||
}
|
||||
|
||||
public boolean understands(IMethod method, Context context) {
|
||||
assert !(context instanceof ScopeMappingContext) || method instanceof AstMethod;
|
||||
return method instanceof AstMethod
|
||||
&& ( (context instanceof ScopeMappingContext)
|
||||
||
|
||||
!((AstMethod)method).lexicalInfo().getAllExposedUses().isEmpty() );
|
||||
}
|
||||
|
||||
public IR getIR(CGNode node) {
|
||||
return getAnalysisCache().getSSACache().findOrCreateIR(node.getMethod(), node.getContext(), options.getSSAOptions());
|
||||
}
|
||||
|
||||
public DefUse getDU(CGNode node) {
|
||||
return getAnalysisCache().getSSACache().findOrCreateDU(node.getMethod(), node.getContext(), options.getSSAOptions());
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,10 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory.AstIR;
|
||||
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
||||
import com.ibm.wala.cast.loader.AstMethod;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalParent;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
|
@ -86,7 +89,7 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
|
|||
|
||||
CallGraph CG = builder.getCallGraph();
|
||||
|
||||
Assertions._assert(CG.getPredNodes(node).hasNext() || toDo == 0);
|
||||
// Assertions._assert(CG.getPredNodes(node).hasNext() || toDo == 0);
|
||||
|
||||
for (Iterator PS = CG.getPredNodes(node); PS.hasNext();) {
|
||||
CGNode pred = (CGNode) PS.next();
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys.ScopeMappingInstanceKey;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
|
||||
public class ScopeMappingKeysContextSelector implements ContextSelector {
|
||||
|
||||
public static final ContextKey scopeKey = new ContextKey() {
|
||||
public String toString() { return "SCOPE KEY"; }
|
||||
};
|
||||
|
||||
public static class ScopeMappingContext implements Context {
|
||||
private final Context base;
|
||||
private final ScopeMappingInstanceKey key;
|
||||
|
||||
private ScopeMappingContext(Context base, ScopeMappingInstanceKey key) {
|
||||
this.base = base;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public ContextItem get(ContextKey name) {
|
||||
if (scopeKey.equals(name)) {
|
||||
return key;
|
||||
} else {
|
||||
return base.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return base.hashCode()*key.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "context for " + key;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof ScopeMappingContext) &&
|
||||
key.equals(((ScopeMappingContext)o).key) &&
|
||||
base.equals(((ScopeMappingContext)o).base);
|
||||
}
|
||||
}
|
||||
|
||||
private final ContextSelector base;
|
||||
|
||||
public ScopeMappingKeysContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) {
|
||||
Context bc = base.getCalleeTarget(caller, site, callee, receiver);
|
||||
if (receiver instanceof ScopeMappingInstanceKey) {
|
||||
return new ScopeMappingContext(bc, (ScopeMappingInstanceKey) receiver);
|
||||
} else {
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.cast.loader.AstMethod;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
|
@ -30,17 +31,18 @@ import com.ibm.wala.ssa.SymbolTable;
|
|||
import com.ibm.wala.ssa.SSACFG.ExceptionHandlerBasicBlock;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class AstIRFactory implements IRFactory {
|
||||
private final boolean keepIR;
|
||||
|
||||
private final Map<IMethod, IR> keptIRs;
|
||||
private final Map<Pair<IMethod,Context>, IR> keptIRs;
|
||||
|
||||
AstIRFactory(boolean keepIR) {
|
||||
this.keepIR = keepIR;
|
||||
|
||||
HashMap<IMethod, IR> m = HashMapFactory.make();
|
||||
HashMap<Pair<IMethod,Context>, IR> m = HashMapFactory.make();
|
||||
this.keptIRs = (keepIR) ? m : null;
|
||||
}
|
||||
|
||||
|
@ -49,8 +51,14 @@ public class AstIRFactory implements IRFactory {
|
|||
}
|
||||
|
||||
public class AstIR extends IR {
|
||||
private final LexicalInformation lexicalInfo;
|
||||
|
||||
private final SSA2LocalMap localMap;
|
||||
|
||||
public LexicalInformation lexicalInfo() {
|
||||
return lexicalInfo;
|
||||
}
|
||||
|
||||
private void setCatchInstructions(SSACFG ssacfg, AbstractCFG oldcfg) {
|
||||
for (int i = 0; i < oldcfg.getNumberOfNodes(); i++)
|
||||
if (oldcfg.isCatchBlock(i)) {
|
||||
|
@ -87,11 +95,13 @@ public class AstIRFactory implements IRFactory {
|
|||
private AstIR(AstMethod method, SSAInstruction[] instructions, SymbolTable symbolTable, SSACFG cfg, SSAOptions options) {
|
||||
super(method, instructions, symbolTable, cfg, options);
|
||||
|
||||
lexicalInfo = method.cloneLexicalInfo();
|
||||
|
||||
localMap = SSAConversion.convert(method, this, options);
|
||||
|
||||
setCatchInstructions(getControlFlowGraph(), method.cfg);
|
||||
setCatchInstructions(getControlFlowGraph(), method.cfg());
|
||||
|
||||
setupCatchTypes(getControlFlowGraph(), method.catchTypes);
|
||||
setupCatchTypes(getControlFlowGraph(), method.catchTypes());
|
||||
|
||||
setupLocationMap();
|
||||
}
|
||||
|
@ -99,20 +109,23 @@ public class AstIRFactory implements IRFactory {
|
|||
|
||||
public IR makeIR(final IMethod method, final Context context, final SSAOptions options) {
|
||||
Assertions._assert(method instanceof AstMethod, method.toString());
|
||||
Pair<IMethod,Context> key = Pair.make(method, context);
|
||||
if (keepIR) {
|
||||
if (keptIRs.containsKey(method)) {
|
||||
return keptIRs.get(method);
|
||||
if (keptIRs.containsKey(key)) {
|
||||
return keptIRs.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
AbstractCFG oldCfg = ((AstMethod) method).cfg;
|
||||
SSAInstruction[] instrs = (SSAInstruction[]) oldCfg.getInstructions();
|
||||
|
||||
IR newIR = new AstIR((AstMethod) method, instrs, ((AstMethod) method).symtab, new SSACFG(method, oldCfg, instrs),
|
||||
AbstractCFG oldCfg = ((AstMethod) method).cfg();
|
||||
SSAInstruction[] oldInstrs = (SSAInstruction[]) oldCfg.getInstructions();
|
||||
SSAInstruction[] instrs = new SSAInstruction[ oldInstrs.length ];
|
||||
System.arraycopy(oldInstrs, 0, instrs, 0, instrs.length);
|
||||
|
||||
IR newIR = new AstIR((AstMethod) method, instrs, ((AstMethod) method).symbolTable(), new SSACFG(method, oldCfg, instrs),
|
||||
options);
|
||||
|
||||
if (keepIR) {
|
||||
keptIRs.put(method, newIR);
|
||||
keptIRs.put(key, newIR);
|
||||
}
|
||||
|
||||
return newIR;
|
||||
|
|
|
@ -448,8 +448,8 @@ public class SSAConversion extends AbstractSSAConversion {
|
|||
: m;
|
||||
|
||||
this.ir = ir;
|
||||
this.debugInfo = M.debugInfo;
|
||||
this.lexicalInfo = M.lexicalInfo;
|
||||
this.debugInfo = M.debugInfo();
|
||||
this.lexicalInfo = ir.lexicalInfo();
|
||||
this.symtab = ir.getSymbolTable();
|
||||
this.R = new Stack[ir.getSymbolTable().getMaxValueNumber() + 1];
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public abstract class AstTranslator extends CAstVisitor implements ArrayOpHandle
|
|||
protected abstract void declareFunction(CAstEntity N, WalkContext context);
|
||||
|
||||
protected abstract void defineFunction(CAstEntity N, WalkContext definingContext, AbstractCFG cfg, SymbolTable symtab,
|
||||
boolean hasCatchBlock, TypeReference[][] caughtTypes, LexicalInformation lexicalInfo, DebuggingInformation debugInfo);
|
||||
boolean hasCatchBlock, TypeReference[][] caughtTypes, AstLexicalInformation lexicalInfo, DebuggingInformation debugInfo);
|
||||
|
||||
protected abstract void defineField(CAstEntity topEntity, WalkContext context, CAstEntity n);
|
||||
|
||||
|
@ -1916,6 +1916,46 @@ public abstract class AstTranslator extends CAstVisitor implements ArrayOpHandle
|
|||
|
||||
private MutableIntSet allExposedUses = null;
|
||||
|
||||
public AstLexicalInformation(AstLexicalInformation original) {
|
||||
if (original.exposedNames != null) {
|
||||
exposedNames = new Pair[ original.exposedNames.length ];
|
||||
for(int i = 0; i < exposedNames.length; i++) {
|
||||
exposedNames[i] = Pair.make(original.exposedNames[i].fst, original.exposedNames[i].snd);
|
||||
}
|
||||
} else {
|
||||
exposedNames = null;
|
||||
}
|
||||
|
||||
instructionLexicalUses = new int[ original.instructionLexicalUses.length ][];
|
||||
for(int i= 0; i < instructionLexicalUses.length; i++) {
|
||||
int[] x = original.instructionLexicalUses[i];
|
||||
if (x != null) {
|
||||
instructionLexicalUses[i] = new int[ x.length ];
|
||||
for(int j = 0; j < x.length; j++) {
|
||||
instructionLexicalUses[i][j] = x[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (original.exitLexicalUses != null) {
|
||||
exitLexicalUses = new int[ original.exitLexicalUses.length ];
|
||||
for(int i = 0; i < exitLexicalUses.length; i++) {
|
||||
exitLexicalUses[i] = original.exitLexicalUses[i];
|
||||
}
|
||||
} else {
|
||||
exitLexicalUses = null;
|
||||
}
|
||||
|
||||
if (original.scopingParents != null) {
|
||||
scopingParents = new String[ original.scopingParents.length ];
|
||||
for(int i = 0; i < scopingParents.length; i++) {
|
||||
scopingParents[i] = original.scopingParents[i];
|
||||
}
|
||||
} else {
|
||||
scopingParents = null;
|
||||
}
|
||||
}
|
||||
|
||||
private int[] buildLexicalUseArray(Pair[] exposedNames) {
|
||||
if (exposedNames != null) {
|
||||
int[] lexicalUses = new int[exposedNames.length];
|
||||
|
@ -2337,7 +2377,7 @@ public abstract class AstTranslator extends CAstVisitor implements ArrayOpHandle
|
|||
// (put here to allow subclasses to handle stuff in scoped entities)
|
||||
// assemble lexical information
|
||||
patchLexicalAccesses(cfg.getInstructions(), accesses.get(n));
|
||||
LexicalInformation LI =
|
||||
AstLexicalInformation LI =
|
||||
// TODO: Ask Julian if the below change is always correct
|
||||
new AstLexicalInformation((AbstractScope) functionContext.currentScope(), cfg.getInstructions(), exposedNames.get(n), accesses
|
||||
.get(n));
|
||||
|
|
|
@ -12,6 +12,7 @@ package com.ibm.wala.cast.loader;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.AstTranslator.AstLexicalInformation;
|
||||
import com.ibm.wala.cast.tree.CAstQualifier;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
|
@ -26,6 +27,7 @@ import com.ibm.wala.types.TypeReference;
|
|||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
public abstract class AstMethod implements IMethod {
|
||||
|
@ -56,15 +58,15 @@ public abstract class AstMethod implements IMethod {
|
|||
|
||||
}
|
||||
|
||||
public final IClass cls;
|
||||
public final Collection qualifiers;
|
||||
public final AbstractCFG cfg;
|
||||
public final SymbolTable symtab;
|
||||
public final MethodReference ref;
|
||||
public final boolean hasCatchBlock;
|
||||
public final TypeReference[][] catchTypes;
|
||||
public final LexicalInformation lexicalInfo;
|
||||
public final DebuggingInformation debugInfo;
|
||||
protected final IClass cls;
|
||||
private final Collection qualifiers;
|
||||
private final AbstractCFG cfg;
|
||||
private final SymbolTable symtab;
|
||||
private final MethodReference ref;
|
||||
private final boolean hasCatchBlock;
|
||||
private final TypeReference[][] catchTypes;
|
||||
private final AstLexicalInformation lexicalInfo;
|
||||
private final DebuggingInformation debugInfo;
|
||||
|
||||
protected AstMethod(IClass cls,
|
||||
Collection qualifiers,
|
||||
|
@ -73,7 +75,7 @@ public abstract class AstMethod implements IMethod {
|
|||
MethodReference ref,
|
||||
boolean hasCatchBlock,
|
||||
TypeReference[][] catchTypes,
|
||||
LexicalInformation lexicalInfo,
|
||||
AstLexicalInformation lexicalInfo,
|
||||
DebuggingInformation debugInfo)
|
||||
{
|
||||
this.cls = cls;
|
||||
|
@ -105,6 +107,34 @@ public abstract class AstMethod implements IMethod {
|
|||
Assertions._assert(isAbstract());
|
||||
}
|
||||
|
||||
public AbstractCFG cfg() {
|
||||
return cfg;
|
||||
}
|
||||
|
||||
public boolean hasCatchBlock() {
|
||||
return hasCatchBlock();
|
||||
}
|
||||
|
||||
public SymbolTable symbolTable() {
|
||||
return symtab;
|
||||
}
|
||||
|
||||
public TypeReference[][] catchTypes() {
|
||||
return catchTypes;
|
||||
}
|
||||
|
||||
public LexicalInformation cloneLexicalInfo() {
|
||||
return new AstLexicalInformation(lexicalInfo);
|
||||
}
|
||||
|
||||
public LexicalInformation lexicalInfo() {
|
||||
return lexicalInfo;
|
||||
}
|
||||
|
||||
public DebuggingInformation debugInfo() {
|
||||
return debugInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parents of this method with respect to lexical scoping, that is,
|
||||
* methods containing state possibly referenced lexically in this
|
||||
|
|
|
@ -31,7 +31,7 @@ import com.ibm.wala.ssa.ISSABasicBlock;
|
|||
*/
|
||||
public class ContextInsensitiveSSAInterpreter extends ContextInsensitiveRTAInterpreter implements SSAContextInterpreter {
|
||||
|
||||
private final AnalysisOptions options;
|
||||
protected final AnalysisOptions options;
|
||||
|
||||
public ContextInsensitiveSSAInterpreter(AnalysisOptions options, AnalysisCache cache) {
|
||||
super(cache);
|
||||
|
|
Loading…
Reference in New Issue