removing lexical reads and writes from invoke instructions; WIP

This commit is contained in:
Manu Sridharan 2013-06-24 14:28:11 -04:00
parent 3bd2f588d0
commit 059d841c8c
10 changed files with 28 additions and 343 deletions

View File

@ -63,8 +63,8 @@ import com.ibm.wala.classLoader.ModuleEntry;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeCT.AnnotationsReader.ElementValue;
import com.ibm.wala.shrikeCT.AnnotationsReader.ConstantElementValue;
import com.ibm.wala.shrikeCT.AnnotationsReader.ElementValue;
import com.ibm.wala.shrikeCT.ClassConstants;
import com.ibm.wala.ssa.SSAThrowInstruction;
import com.ibm.wala.ssa.SymbolTable;
@ -551,19 +551,8 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
}
@Override
public AstJavaInvokeInstruction JavaInvokeInstruction(int result, int[] params, int exception, CallSiteReference site) {
return new AstJavaInvokeInstruction(result, params, exception, site);
}
@Override
public AstJavaInvokeInstruction JavaInvokeInstruction(int[] params, int exception, CallSiteReference site) {
return new AstJavaInvokeInstruction(params, exception, site);
}
@Override
public AstJavaInvokeInstruction JavaInvokeInstruction(int[] results, int[] params, int exception, CallSiteReference site,
Access[] lexicalReads, Access[] lexicalWrites) {
return new AstJavaInvokeInstruction(results, params, exception, site, lexicalReads, lexicalWrites);
public AstJavaInvokeInstruction JavaInvokeInstruction(int result[], int[] params, int exception, CallSiteReference site) {
return new AstJavaInvokeInstruction(result[0], params, exception, site);
}
@Override

View File

@ -11,19 +11,14 @@
package com.ibm.wala.cast.java.ssa;
import com.ibm.wala.cast.ir.ssa.AstInstructionFactory;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.types.TypeReference;
public interface AstJavaInstructionFactory extends AstInstructionFactory {
AstJavaInvokeInstruction JavaInvokeInstruction(int result, int[] params, int exception, CallSiteReference site);
AstJavaInvokeInstruction JavaInvokeInstruction(int result[], int[] params, int exception, CallSiteReference site);
AstJavaInvokeInstruction JavaInvokeInstruction(int[] params, int exception, CallSiteReference site);
AstJavaInvokeInstruction JavaInvokeInstruction(int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites);
EnclosingObjectReference EnclosingObjectReference(int lval, TypeReference type);
AstJavaNewEnclosingInstruction JavaNewEnclosingInstruction(int result, NewSiteReference site, int enclosing);

View File

@ -12,7 +12,6 @@ package com.ibm.wala.cast.java.ssa;
import java.util.Collection;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.cast.ir.ssa.FixedParametersLexicalInvokeInstruction;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.JavaLanguage;
@ -21,13 +20,6 @@ import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.types.TypeReference;
/**
* This is a normal Java invoke instruction as generated by the CAst source language front end; its only difference from the normal
* SSAInvokeInstruction is that it is subclassed from invoke instructions that support explicit handling of lexical scoping. So it
* behaves exactly like an invoke from bytecode, except that it has extra state for managing lexical uses and definitions.
*
* @author Julian Dolby (dolby@us.ibm.com)
*/
public class AstJavaInvokeInstruction extends FixedParametersLexicalInvokeInstruction {
protected AstJavaInvokeInstruction(int results[], int[] params, int exception, CallSiteReference site) {
@ -46,34 +38,24 @@ public class AstJavaInvokeInstruction extends FixedParametersLexicalInvokeInstru
this(null, params, exception, site);
}
public AstJavaInvokeInstruction(int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads,
Access[] lexicalWrites) {
super(results, params, exception, site, lexicalReads, lexicalWrites);
}
@Override
protected SSAInstruction copyInstruction(SSAInstructionFactory insts, int results[], int[] params, int exception,
Access[] lexicalReads, Access[] lexicalWrites) {
return ((AstJavaInstructionFactory) insts).JavaInvokeInstruction(results, params, exception, getCallSite(), lexicalReads,
lexicalWrites);
protected SSAInstruction copyInstruction(SSAInstructionFactory insts, int results[], int[] params, int exception) {
return ((AstJavaInstructionFactory) insts).JavaInvokeInstruction(results, params, exception, getCallSite());
}
/**
* @see com.ibm.domo.ssa.SSAInstruction#visit(IVisitor)
*/
@Override
public void visit(IVisitor v) {
((AstJavaInstructionVisitor) v).visitJavaInvoke(this);
}
/*
* (non-Javadoc)
*
* @see com.ibm.domo.ssa.Instruction#getExceptionTypes()
*/
@Override
public Collection<TypeReference> getExceptionTypes() {
return JavaLanguage.getNullPointerException();
}
@Override
public int hashCode() {
return (site.hashCode() * 7529) + (exception * 9823);
}
}

View File

@ -233,12 +233,6 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
return new JavaScriptInvoke(function, results, params, exception, site);
}
@Override
public JavaScriptInvoke Invoke(int function, int[] results, int[] params, int exception, CallSiteReference site,
Access[] lexicalReads, Access[] lexicalWrites) {
return new JavaScriptInvoke(function, results, params, exception, site, lexicalReads, lexicalWrites);
}
@Override
public JavaScriptInvoke Invoke(int function, int result, int[] params, int exception, CallSiteReference site) {
return new JavaScriptInvoke(function, result, params, exception, site);

View File

@ -26,8 +26,6 @@ public interface JSInstructionFactory extends AstInstructionFactory {
JavaScriptInvoke Invoke(int function, int results[], int[] params, int exception, CallSiteReference site);
JavaScriptInvoke Invoke(int function, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites);
JavaScriptInvoke Invoke(int function, int result, int[] params, int exception, CallSiteReference site);
JavaScriptInvoke Invoke(int function, int[] params, int exception, CallSiteReference site);

View File

@ -12,8 +12,7 @@ package com.ibm.wala.cast.js.ssa;
import java.util.Collection;
import com.ibm.wala.cast.ir.ssa.AbstractLexicalInvoke;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.cast.ir.ssa.MultiReturnValueInvokeInstruction;
import com.ibm.wala.cast.js.types.JavaScriptMethods;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.ssa.SSAInstruction;
@ -21,7 +20,7 @@ import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.types.TypeReference;
public class JavaScriptInvoke extends AbstractLexicalInvoke {
public class JavaScriptInvoke extends MultiReturnValueInvokeInstruction {
/**
* The value numbers of the arguments passed to the call.
*/
@ -35,13 +34,6 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
this.params = params;
}
public JavaScriptInvoke(int function, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads,
Access[] lexicalWrites) {
super(results, exception, site, lexicalReads, lexicalWrites);
this.function = function;
this.params = params;
}
public JavaScriptInvoke(int function, int result, int[] params, int exception, CallSiteReference site) {
this(function, new int[] { result }, params, exception, site);
}
@ -54,7 +46,6 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses) {
int fn = function;
int newParams[] = params;
Access[] reads = lexicalReads;
if (uses != null) {
int i = 0;
@ -65,17 +56,11 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
for (int j = 0; j < newParams.length; j++)
newParams[j] = uses[i++];
if (lexicalReads != null) {
reads = new Access[lexicalReads.length];
for (int j = 0; j < reads.length; j++)
reads[j] = new Access(lexicalReads[j].variableName, lexicalReads[j].variableDefiner, uses[i++]);
}
}
int newLvals[] = new int[results.length];
System.arraycopy(results, 0, newLvals, 0, results.length);
int newExp = exception;
Access[] writes = lexicalWrites;
if (defs != null) {
int i = 0;
@ -87,14 +72,9 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
newLvals[j] = defs[i++];
}
if (lexicalWrites != null) {
writes = new Access[lexicalWrites.length];
for (int j = 0; j < writes.length; j++)
writes[j] = new Access(lexicalWrites[j].variableName, lexicalWrites[j].variableDefiner, defs[i++]);
}
}
return ((JSInstructionFactory)insts).Invoke(fn, newLvals, newParams, newExp, site, reads, writes);
return ((JSInstructionFactory)insts).Invoke(fn, newLvals, newParams, newExp, site);
}
@Override
@ -130,30 +110,9 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
s.append(" exception:").append(getValueString(symbolTable, exception));
}
if (lexicalReads != null) {
s.append(" (reads:");
for (int i = 0; i < lexicalReads.length; i++) {
s.append(" ").append(lexicalReads[i].variableName).append(":").append(
getValueString(symbolTable, lexicalReads[i].valueNumber));
}
s.append(")");
}
if (lexicalWrites != null) {
s.append(" (writes:");
for (int i = 0; i < lexicalWrites.length; i++) {
s.append(" ").append(lexicalWrites[i].variableName).append(":").append(
getValueString(symbolTable, lexicalWrites[i].valueNumber));
}
s.append(")");
}
return s.toString();
}
/**
* @see com.ibm.domo.ssa.Instruction#visit(Visitor)
*/
@Override
public void visit(IVisitor v) {
assert v instanceof JSInstructionVisitor;
@ -169,9 +128,6 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
}
}
/**
* @see com.ibm.domo.ssa.Instruction#getUse(int)
*/
@Override
public int getUse(int j) {
if (j == 0)

View File

@ -18,7 +18,6 @@ import java.util.Set;
import com.ibm.wala.analysis.reflection.ReflectionContextInterpreter;
import com.ibm.wala.cast.ipa.callgraph.AstCallGraph.AstCGNode;
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys.ScopeMappingInstanceKey;
import com.ibm.wala.cast.ir.ssa.AbstractLexicalInvoke;
import com.ibm.wala.cast.ir.ssa.AstAssertInstruction;
import com.ibm.wala.cast.ir.ssa.AstEchoInstruction;
import com.ibm.wala.cast.ir.ssa.AstGlobalRead;
@ -61,7 +60,6 @@ import com.ibm.wala.ipa.callgraph.propagation.cfa.DelegatingSSAContextInterprete
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.DefUse;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.util.collections.HashSetFactory;
@ -535,43 +533,6 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
}
@Override
protected void visitInvokeInternal(final SSAAbstractInvokeInstruction instruction, InvariantComputer invs) {
super.visitInvokeInternal(instruction, invs);
if (instruction instanceof AbstractLexicalInvoke) {
AbstractLexicalInvoke I = (AbstractLexicalInvoke) instruction;
for (int wi = 0; wi < I.getNumberOfDefs(); wi++) {
if (I.isLexicalDef(wi)) {
Access w = I.getLexicalDef(wi);
for (int ri = 0; ri < I.getNumberOfUses(); ri++) {
if (I.isLexicalUse(ri)) {
Access r = I.getLexicalUse(ri);
if (w.variableName.equals(r.variableName)) {
if (w.variableDefiner == null ? r.variableDefiner == null : w.variableDefiner.equals(r.variableDefiner)) {
// handle the control-flow paths through the (transitive)
// callees where the name is not written;
// in such cases, the original value (rk) is preserved
PointerKey rk = getBuilder().getPointerKeyForLocal(node, r.valueNumber);
PointerKey wk = getBuilder().getPointerKeyForLocal(node, w.valueNumber);
if (contentsAreInvariant(node.getIR().getSymbolTable(), du, r.valueNumber)) {
system.recordImplicitPointsToSet(rk);
final InstanceKey[] objKeys = getInvariantContents(r.valueNumber);
for (int i = 0; i < objKeys.length; i++) {
system.newConstraint(wk, objKeys[0]);
}
} else {
system.newConstraint(wk, assignOperator, rk);
}
}
}
}
}
}
}
}
}
// /////////////////////////////////////////////////////////////////////////
//
// lexical scoping handling
@ -949,8 +910,8 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
@Override
public byte evaluate(PointsToSetVariable lhs, final PointsToSetVariable[] rhs) {
final IntSetVariable receivers = (IntSetVariable) rhs[0];
final IntSetVariable fields = (IntSetVariable) rhs[1];
final IntSetVariable receivers = rhs[0];
final IntSetVariable fields = rhs[1];
if (receivers.getValue() != null && fields.getValue() != null) {
receivers.getValue().foreach(new IntSetAction() {
@Override

View File

@ -1,168 +0,0 @@
/******************************************************************************
* 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.ir.ssa;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.ssa.SymbolTable;
/**
* This abstract class adds to invoke instructions the ability to handle lexical uses and definitions during call graph
* construction. The lexical uses and definitions of these objects are initially empty, and get filled in by the
* AstSSAPropagationCallGraphBuilder, particularly its LexicalOperator objects. This class is still abstract since the
* lexical scoping functionality is used by multiple languages, each of which has further specializations of invoke
* instructions.
*
* @author Julian Dolby (dolby@us.ibm.com)
*
*/
public abstract class AbstractLexicalInvoke extends MultiReturnValueInvokeInstruction {
protected Access[] lexicalReads = null;
protected Access[] lexicalWrites = null;
protected AbstractLexicalInvoke(int results[], int exception, CallSiteReference site) {
super(results, exception, site);
}
protected AbstractLexicalInvoke(int result, int exception, CallSiteReference site) {
this(new int[] { result }, exception, site);
}
protected AbstractLexicalInvoke(int results[], int exception, CallSiteReference site, Access[] lexicalReads,
Access[] lexicalWrites) {
this(results, exception, site);
this.lexicalReads = lexicalReads;
this.lexicalWrites = lexicalWrites;
}
@Override
public int getNumberOfUses() {
if (lexicalReads == null)
return getNumberOfParameters();
else
return getNumberOfParameters() + lexicalReads.length;
}
public int getNumberOfLexicalWrites(){
if(lexicalWrites == null){
return 0;
} else {
return lexicalWrites.length;
}
}
public int getNumberOfLexicalReads() {
if(lexicalReads == null){
return 0;
} else {
return lexicalReads.length;
}
}
public final int getLastLexicalUse() {
if (lexicalReads == null) {
return -1;
} else {
return getNumberOfParameters() + lexicalReads.length - 1;
}
}
@Override
public int getUse(int j) {
assert j >= getNumberOfParameters();
assert lexicalReads != null;
assert lexicalReads[j - getNumberOfParameters()] != null;
return lexicalReads[j - getNumberOfParameters()].valueNumber;
}
@Override
public int getNumberOfDefs() {
if (lexicalWrites == null)
return super.getNumberOfDefs();
else
return super.getNumberOfDefs() + lexicalWrites.length;
}
@Override
public int getDef(int j) {
if (j < super.getNumberOfDefs())
return super.getDef(j);
else
return lexicalWrites[j - super.getNumberOfDefs()].valueNumber;
}
private Access[] addAccess(Access[] array, Access access) {
if (array == null)
return new Access[] { access };
else {
Access[] result = new Access[array.length + 1];
System.arraycopy(array, 0, result, 0, array.length);
result[array.length] = access;
return result;
}
}
public boolean isLexicalUse(int use) {
return use >= getNumberOfParameters();
}
public void addLexicalUse(Access use) {
lexicalReads = addAccess(lexicalReads, use);
}
public Access getLexicalUse(int i) {
return lexicalReads[i - getNumberOfParameters()];
}
public boolean isLexicalDef(int def) {
return def >= super.getNumberOfDefs();
}
public void addLexicalDef(Access def) {
lexicalWrites = addAccess(lexicalWrites, def);
}
public Access getLexicalDef(int i) {
return lexicalWrites[i - super.getNumberOfDefs()];
}
@Override
public int hashCode() {
return site.hashCode() * 7529;
}
@Override
public String toString(SymbolTable symbolTable) {
StringBuffer s = new StringBuffer(super.toString(symbolTable));
if (lexicalReads != null) {
s.append(" (reads:");
for (int i = 0; i < lexicalReads.length; i++) {
s.append(" ").append(lexicalReads[i].variableName).append(":").append(
getValueString(symbolTable, lexicalReads[i].valueNumber));
}
s.append(")");
}
if (lexicalWrites != null) {
s.append(" (writes:");
for (int i = 0; i < lexicalWrites.length; i++) {
s.append(" ").append(lexicalWrites[i].variableName).append(":").append(
getValueString(symbolTable, lexicalWrites[i].valueNumber));
}
s.append(")");
}
return s.toString();
}
}

View File

@ -10,7 +10,6 @@
*****************************************************************************/
package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInstructionFactory;
@ -24,7 +23,7 @@ import com.ibm.wala.ssa.SSAInstructionFactory;
* @author Julian Dolby (dolby@us.ibm.com)
*/
public abstract class FixedParametersLexicalInvokeInstruction
extends AbstractLexicalInvoke
extends MultiReturnValueInvokeInstruction
{
/**
@ -52,57 +51,39 @@ public abstract class FixedParametersLexicalInvokeInstruction
this(null, params, exception, site);
}
protected FixedParametersLexicalInvokeInstruction(int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites) {
super(results, exception, site, lexicalReads, lexicalWrites);
this.params = params;
}
protected abstract SSAInstruction copyInstruction(SSAInstructionFactory insts, int result[], int[] params, int exception, Access[] lexicalReads, Access[] lexicalWrites);
protected abstract SSAInstruction copyInstruction(SSAInstructionFactory insts, int result[], int[] params, int exception);
@Override
public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses) {
int newParams[] = params;
Access[] reads = lexicalReads;
if (uses != null) {
int i = 0;
newParams = new int[ params.length ];
for(int j = 0; j < newParams.length; j++)
newParams[j] = uses[i++];
if (lexicalReads != null) {
reads = new Access[ lexicalReads.length ];
for(int j = 0; j < reads.length; j++)
reads[j] = new Access(lexicalReads[j].variableName, lexicalReads[j].variableDefiner, uses[i++]);
}
newParams = new int[params.length];
for (int j = 0; j < newParams.length; j++)
newParams[j] = uses[i++];
}
int newLvals[] = null;
if (getNumberOfReturnValues() > 0) {
newLvals = new int[ results.length ];
newLvals = new int[results.length];
System.arraycopy(results, 0, newLvals, 0, results.length);
}
int newExp = exception;
Access[] writes = lexicalWrites;
if (defs != null) {
int i = 0;
if (getNumberOfReturnValues() > 0) {
newLvals[0] = defs[i++];
newLvals[0] = defs[i++];
}
newExp = defs[i++];
for(int j = 1; j < getNumberOfReturnValues(); j++) {
newLvals[j] = defs[i++];
}
if (lexicalWrites != null) {
writes = new Access[ lexicalWrites.length ];
for(int j = 0; j < writes.length; j++)
writes[j] = new Access(lexicalWrites[j].variableName, lexicalWrites[j].variableDefiner, defs[i++]);
for (int j = 1; j < getNumberOfReturnValues(); j++) {
newLvals[j] = defs[i++];
}
}
return copyInstruction(insts, newLvals, newParams, newExp, reads, writes);
return copyInstruction(insts, newLvals, newParams, newExp);
}
@Override
@ -114,9 +95,6 @@ public abstract class FixedParametersLexicalInvokeInstruction
}
}
/**
* @see com.ibm.wala.ssa.Instruction#getUse(int)
*/
@Override
public int getUse(int j) {
if (j < getNumberOfParameters())

View File

@ -13,7 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
abstract class MultiReturnValueInvokeInstruction
public abstract class MultiReturnValueInvokeInstruction
extends SSAAbstractInvokeInstruction
{
protected final int results[];