new test to remind me that prototype no longer works with correlation tracking:
com.ibm.wala.cast.js.rhino.test/harness-src/com/ibm/wala/cast/js/test/TestPrototypeCallGraphShapeRhino.java com.ibm.wala.cast.js.test/harness-src/com/ibm/wala/cast/js/test/TestPrototypeCallGraphShape.java com.ibm.wala.cast.js.test.data/examples-src/pages/prototype.html work (not yet finished) on fixes to property accesses for JavaScript: com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/AstSSAPropagationCallGraphBuilder.java com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/JSSSAPropagationCallGraphBuilder.java currently unused tests to remind me to fix bugs: com.ibm.wala.cast.js.test/harness-src/com/ibm/wala/cast/js/test/TestSimpleCallGraphShape.java com.ibm.wala.cast.js.test.data/examples-src/tests/loops.js com.ibm.wala.cast.js.test.data/examples-src/tests/primitive_strings.js fixes to exception handler code generation in JavaScript: com.ibm.wala.cast.js.rhino/source/com/ibm/wala/cast/js/translator/RhinoToAstTranslator.java com.ibm.wala.cast.js.test.data/examples-src/tests/try.js com.ibm.wala.cast.js.test/harness-src/com/ibm/wala/cast/js/test/TestSimpleCallGraphShape.java fixes to make the system build on both juno and luna com.ibm.wala.cast.js.test.data/pom.xml pom.xml targets/e42/e42.target targets/e44/e44.target targets/pom.xml com.ibm.wala.core.tests/META-INF/MANIFEST.MF com.ibm.wala.dalvik.test/META-INF/MANIFEST.MF com.ibm.wala.ide.jdt.test/META-INF/MANIFEST.MF com.ibm.wala.ide.jdt/source/com/ibm/wala/cast/java/translator/jdt/FakeExceptionTypeBinding.java com.ibm.wala.ide.jdt/source/com/ibm/wala/ide/util/JavaEclipseProjectPath.java com.ibm.wala.ide.jsdt.tests/META-INF/MANIFEST.MF com.ibm.wala.ide.jsdt.tests/src/com/ibm/wala/ide/jsdt/tests/AbstractJSProjectScopeTest.java com.ibm.wala.ide/src/com/ibm/wala/ide/util/EclipseProjectPath.java com.ibm.wala.ide/src/com/ibm/wala/ide/util/ProgressMonitorDelegate.java beginnings of "pointer analysis" on top of field-based analysis com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/callgraph/fieldbased/flowgraph/FlowGraph.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/callgraph/fieldbased/flowgraph/vertices/PropVertex.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/callgraph/fieldbased/flowgraph/vertices/RetVertex.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/callgraph/fieldbased/flowgraph/vertices/VarVertex.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/callgraph/fieldbased/flowgraph/vertices/VertexFactory.java com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerAnalysis.java com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/cfa/ExceptionReturnValueKey.java fixes for crashes in correlartion tracking com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ipa/callgraph/correlations/extraction/ClosureExtractor.java fixes for Dalvik IR generation com.ibm.wala.core/src/com/ibm/wala/cfg/BytecodeCFG.java com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java com.ibm.wala.dalvik.test/source/com/ibm/wala/dalvik/drivers/APKCallGraphDriver.java com.ibm.wala.dalvik.test/source/com/ibm/wala/dalvik/test/callGraph/JVMLDalvikComparison.java com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/DexCFG.java com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/dex/instructions/UnaryOperation.java com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/ssa/AbstractIntRegisterMachine.java com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/ssa/DexSSABuilder.java fixes to stack map generation when instrumenting for Java 7 com.ibm.wala.shrike/src/com/ibm/wala/shrike/cg/DynamicCallGraph.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/StackMapConstants.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/StackMapTableReader.java com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/StackMapTableWriter.java
This commit is contained in:
parent
d949561e39
commit
c9ad359d65
|
@ -56,6 +56,12 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractFieldPointerKey fieldKeyForUnknownWrites(AbstractFieldPointerKey fieldKey) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// enclosing object pointer flow support
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/******************************************************************************
|
||||
* 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.js.test;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
|
||||
public class TestPrototypeCallGraphShapeRhino extends TestPrototypeCallGraphShape {
|
||||
|
||||
public static void main(String[] args) {
|
||||
justThisTest(TestPrototypeCallGraphShapeRhino.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() {
|
||||
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
}
|
|
@ -1326,7 +1326,16 @@ public class RhinoToAstTranslator {
|
|||
CAstNode tryCatch;
|
||||
|
||||
if (catches != null && catches.size() > 0) {
|
||||
CAstNode var = Ast.makeConstant(catches.get(0).getVarName().getString());
|
||||
String catchVarName = catches.get(0).getVarName().getString();
|
||||
CAstNode var = Ast.makeConstant(catchVarName);
|
||||
|
||||
arg.addNameDecl(
|
||||
noteSourcePosition(
|
||||
arg,
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(catchVarName, JSAstTranslator.Any)),
|
||||
readName(arg, null, "$$undefined")),
|
||||
node));
|
||||
|
||||
CAstNode code = Ast.makeNode(CAstNode.THROW, var);
|
||||
for(int i = catches.size()-1; i >= 0; i--) {
|
||||
CatchClause clause = catches.get(i);
|
||||
|
@ -1340,7 +1349,9 @@ public class RhinoToAstTranslator {
|
|||
arg.cfg().map(catchBlock, catchBlock);
|
||||
|
||||
TryCatchContext tryContext = new TryCatchContext(arg, catchBlock);
|
||||
tryCatch = Ast.makeNode(CAstNode.TRY, visit(node.getTryBlock(), tryContext), catchBlock);
|
||||
tryCatch = Ast.makeNode(CAstNode.TRY,
|
||||
visit(node.getTryBlock(), tryContext),
|
||||
/*Ast.makeNode(CAstNode.LOCAL_SCOPE,*/ catchBlock/*)*/);
|
||||
} else {
|
||||
tryCatch = visit(node.getTryBlock(), arg);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<SCRIPT src="http://ajax.googleapis.com/ajax/libs/prototype/1.7.0/prototype.js"/>
|
||||
</HEAD>
|
||||
</HTML>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
var fs = [ function one() { return "one" },
|
||||
function two() { return "two" },
|
||||
function three() { return "three" },
|
||||
function four() { return "four" } ];
|
||||
|
||||
var fs2 = [];
|
||||
|
||||
(function _loop(fs1, fs2) {
|
||||
for(var i = 0; i < fs.length; i++) {
|
||||
fs2[i] = i;
|
||||
}
|
||||
})(fs1, fs2);
|
||||
|
||||
fs[fs2[2]]();
|
||||
fs[fs2[3]]();
|
|
@ -0,0 +1,10 @@
|
|||
function f1() {
|
||||
return "abc".concat("def");
|
||||
}
|
||||
|
||||
function f2() {
|
||||
return new String("abc").concat(new String("def"));
|
||||
}
|
||||
|
||||
f1();
|
||||
f2();
|
|
@ -56,6 +56,29 @@ function tryCatchFinally( x, targetOne, targetTwo ) {
|
|||
}
|
||||
}
|
||||
|
||||
function tryCatchTwice( x, targetOne, targetTwo ) {
|
||||
|
||||
try {
|
||||
if (x.one < 7)
|
||||
targetOne( x );
|
||||
else
|
||||
targetTwo( x );
|
||||
} catch (e) {
|
||||
e.two();
|
||||
}
|
||||
|
||||
try {
|
||||
if (x.one < 7)
|
||||
targetOne( x );
|
||||
else
|
||||
targetTwo( x );
|
||||
} catch (e) {
|
||||
e.three();
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
o = {
|
||||
one: -12,
|
||||
|
||||
|
@ -72,5 +95,11 @@ tryCatch(o, targetOne, targetTwo);
|
|||
tryFinally(o, targetOne, targetTwo);
|
||||
tryFinallyLoop(o, targetTwo);
|
||||
tryCatchFinally(o, targetOne, targetTwo);
|
||||
(function testRet() {
|
||||
var e = tryCatchTwice(o, targetOne, targetTwo);
|
||||
e.two();
|
||||
e.three();
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -29,16 +29,7 @@
|
|||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${java.home}/../lib/tools.jar</systemPath>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/******************************************************************************
|
||||
* 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.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
|
||||
public abstract class TestPrototypeCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
public static void main(String[] args) {
|
||||
justThisTest(TestPrototypeCallGraphShape.class);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForPrototype = new Object[][] {
|
||||
|
||||
};
|
||||
|
||||
@Ignore("reminder that this no longer works with correlation tracking")
|
||||
@Test
|
||||
public void testPrototype() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/prototype.html");
|
||||
CallGraph CG = JSCallGraphBuilderUtil.makeHTMLCG(url);
|
||||
verifyGraphAssertions(CG, assertionsForPrototype);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,8 +13,8 @@ package com.ibm.wala.cast.js.test;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
||||
|
@ -215,11 +215,23 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
new Object[] { "tests/try.js/tryFinally",
|
||||
new String[] { "tests/try.js/targetOne", "tests/try.js/targetTwo", "tests/try.js/two" } },
|
||||
new Object[] { "tests/try.js/tryCatchFinally",
|
||||
new String[] { "tests/try.js/targetOne", "tests/try.js/targetTwo", "tests/try.js/three", "tests/try.js/two" } } };
|
||||
new String[] { "tests/try.js/targetOne", "tests/try.js/targetTwo", "tests/try.js/three", "tests/try.js/two" } },
|
||||
new Object[] { "tests/try.js/tryCatchTwice",
|
||||
new String[] { "tests/try.js/targetOne", "tests/try.js/targetTwo", "tests/try.js/three", "tests/try.js/two" } },
|
||||
new Object[] { "tests/try.js/testRet",
|
||||
new String[] { "tests/try.js/three", "tests/try.js/two" } }
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testTry() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
CallGraph CG = JSCallGraphBuilderUtil.makeScriptCG("tests", "try.js");
|
||||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "try.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
/*
|
||||
boolean x = CAstCallGraphUtil.AVOID_DUMP;
|
||||
CAstCallGraphUtil.AVOID_DUMP = false;
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.AVOID_DUMP = x;
|
||||
*/
|
||||
verifyGraphAssertions(CG, assertionsForTry);
|
||||
}
|
||||
|
||||
|
@ -718,6 +730,42 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
// verifyGraphAssertions(CG, assertionsForDateProperty);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForLoops = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "tests/loops.js" } },
|
||||
new Object[] { "tests/loops.js", new String[] { "tests/loops.js/three", "tests/loops.js/four"} }
|
||||
};
|
||||
|
||||
@Ignore("need to fix this. bug from Sukyoung's group")
|
||||
@Test
|
||||
public void testLoops() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "loops.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
boolean x = CAstCallGraphUtil.AVOID_DUMP;
|
||||
CAstCallGraphUtil.AVOID_DUMP = false;
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.AVOID_DUMP = x;
|
||||
verifyGraphAssertions(CG, assertionsForLoops);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForPrimitiveStrings = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "tests/primitive_strings.js" } },
|
||||
new Object[] { "tests/primitive_strings.js", new String[] { "tests/primitive_strings.js/f1", "tests/primitive_strings.js/f1"} },
|
||||
new Object[] { "tests/primitive_strings.js/f2", new String[] { "prologue.js/String_prototype_concat" } },
|
||||
new Object[] { "tests/primitive_strings.js/f1", new String[] { "prologue.js/String_prototype_concat" } },
|
||||
};
|
||||
|
||||
@Ignore("need to fix this. bug from Sukyoung's group")
|
||||
@Test
|
||||
public void testPrimitiveStrings() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "primitive_strings.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
boolean x = CAstCallGraphUtil.AVOID_DUMP;
|
||||
CAstCallGraphUtil.AVOID_DUMP = false;
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.AVOID_DUMP = x;
|
||||
verifyGraphAssertions(CG, assertionsForPrimitiveStrings);
|
||||
}
|
||||
|
||||
Object[][] renamingAssertions = {
|
||||
{ "tests/rename-example.js/f", new Name[]{ new Name(9, 7, "x"), new Name(9, 7, "y") } },
|
||||
{ "tests/rename-example.js/ff", new Name[]{ new Name(11, 10, "x"), new Name(11, 10, "y"), new Name(11, 10, "z") } }
|
||||
|
|
|
@ -20,13 +20,22 @@ import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.UnknownVerte
|
|||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VarVertex;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.Vertex;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VertexFactory;
|
||||
import com.ibm.wala.cast.types.AstMethodReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.ProgramCounter;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey.TypeFilter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.Predicate;
|
||||
|
@ -162,7 +171,17 @@ public class FlowGraph implements Iterable<Vertex> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public OrdinalSetMapping<InstanceKey> getInstanceKeyMapping() {
|
||||
public Collection<FuncVertex> getInstanceKeys() {
|
||||
return factory.getFuncVertices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(PointerKey pk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrdinalSetMapping<FuncVertex> getInstanceKeyMapping() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
@ -173,21 +192,114 @@ public class FlowGraph implements Iterable<Vertex> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<InstanceKey> getInstanceKeys() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiltered(PointerKey pk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeapModel getHeapModel() {
|
||||
assert false;
|
||||
return null;
|
||||
return new HeapModel() {
|
||||
|
||||
private FuncVertex getVertex(CGNode n) {
|
||||
IMethod m = n.getMethod();
|
||||
if (m.getSelector().equals(AstMethodReference.fnSelector)) {
|
||||
IClass fun = m.getDeclaringClass();
|
||||
return factory.makeFuncVertex(fun);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForLocal(CGNode node, int valueNumber) {
|
||||
FuncVertex function = getVertex(node);
|
||||
if (function != null) {
|
||||
return factory.makeVarVertex(function, valueNumber);
|
||||
} else {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForReturnValue(CGNode node) {
|
||||
FuncVertex function = getVertex(node);
|
||||
if (function != null) {
|
||||
return factory.makeRetVertex(function);
|
||||
} else {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForInstanceField(InstanceKey I, IField field) {
|
||||
String f = field.getName().toString();
|
||||
return factory.makePropVertex(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceKey getInstanceKeyForMultiNewArray(CGNode node, NewSiteReference allocation, int dim) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter instr, TypeReference type) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceKey getInstanceKeyForMetadataObject(Object obj, TypeReference objType) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FilteredPointerKey getFilteredPointerKeyForLocal(CGNode node, int valueNumber, TypeFilter filter) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForExceptionalReturnValue(CGNode node) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForStaticField(IField f) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForArrayContents(InstanceKey I) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PointerKey> iteratePointerKeys() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClassHierarchy getClassHierarchy() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
/**
|
||||
* A property vertex represents all properties with a given name.
|
||||
*
|
||||
* @author mschaefer
|
||||
*
|
||||
*/
|
||||
public class PropVertex extends Vertex {
|
||||
public class PropVertex extends Vertex implements PointerKey {
|
||||
private final String propName;
|
||||
|
||||
PropVertex(String propName) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
|
||||
/**
|
||||
* A return vertex represents all return values of a given function.
|
||||
|
@ -17,7 +19,7 @@ package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
|||
* @author mschaefer
|
||||
*
|
||||
*/
|
||||
public class RetVertex extends Vertex {
|
||||
public class RetVertex extends Vertex implements PointerKey {
|
||||
private final FuncVertex func;
|
||||
|
||||
RetVertex(FuncVertex func) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
|
||||
/**
|
||||
* A variable vertex represents an SSA variable inside a given function.
|
||||
|
@ -17,7 +19,7 @@ package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
|||
* @author mschaefer
|
||||
*
|
||||
*/
|
||||
public final class VarVertex extends Vertex {
|
||||
public final class VarVertex extends Vertex implements PointerKey {
|
||||
private final FuncVertex func;
|
||||
private final int valueNumber;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
||||
|
@ -55,7 +56,7 @@ public class VertexFactory {
|
|||
return value;
|
||||
}
|
||||
|
||||
public Iterable<FuncVertex> getFuncVertices() {
|
||||
public Collection<FuncVertex> getFuncVertices() {
|
||||
return funcVertexCache.values();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Set;
|
|||
|
||||
import com.ibm.wala.analysis.typeInference.TypeInference;
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstSSAPropagationCallGraphBuilder;
|
||||
import com.ibm.wala.cast.ipa.callgraph.ReflectedFieldPointerKey;
|
||||
import com.ibm.wala.cast.ir.ssa.AstGlobalRead;
|
||||
import com.ibm.wala.cast.ir.ssa.AstGlobalWrite;
|
||||
import com.ibm.wala.cast.ir.ssa.AstIsDefinedInstruction;
|
||||
|
@ -169,6 +170,13 @@ public class JSSSAPropagationCallGraphBuilder extends AstSSAPropagationCallGraph
|
|||
|| "class".equals(fieldName) || "$value".equals(fieldName) || "__proto__".equals(fieldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractFieldPointerKey fieldKeyForUnknownWrites(AbstractFieldPointerKey fieldKey) {
|
||||
// TODO: fix this. null is wrong.
|
||||
return null;
|
||||
// return ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(cha.lookupClass(JavaScriptTypes.String)), fieldKey.getInstanceKey());
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// top-level node constraint generation
|
||||
|
|
|
@ -295,14 +295,20 @@ public class ClosureExtractor extends CAstRewriterExt {
|
|||
epos.addGotoTarget(root.getChildCount() > 0 ? (String)root.getChild(0).getValue(): null, target);
|
||||
int label = labeller.addNode(target);
|
||||
// return { type: 'goto', target: <label> }
|
||||
CAstNode returnLit = Ast.makeNode(OBJECT_LITERAL,
|
||||
addExnFlow(Ast.makeNode(CALL,
|
||||
addExnFlow(makeVarRef("Object"), JavaScriptTypes.ReferenceError, getCurrentEntity(), context),
|
||||
Ast.makeConstant("ctor")), null, getCurrentEntity(), context),
|
||||
Ast.makeConstant("type"),
|
||||
Ast.makeConstant("goto"),
|
||||
Ast.makeConstant("target"),
|
||||
Ast.makeConstant(((double)label)+""));
|
||||
CAstNode returnLit =
|
||||
addNode(
|
||||
Ast.makeNode(OBJECT_LITERAL,
|
||||
addExnFlow(
|
||||
Ast.makeNode(CALL,
|
||||
addExnFlow(makeVarRef("Object"), JavaScriptTypes.ReferenceError, getCurrentEntity(), context),
|
||||
Ast.makeConstant("ctor")),
|
||||
null, getCurrentEntity(), context),
|
||||
Ast.makeConstant("type"),
|
||||
Ast.makeConstant("goto"),
|
||||
Ast.makeConstant("target"),
|
||||
Ast.makeConstant(((double)label)+"")),
|
||||
getCurrentEntity().getControlFlow());
|
||||
|
||||
addNode(returnLit, getCurrentEntity().getControlFlow());
|
||||
CAstNode newNode = Ast.makeNode(RETURN, returnLit);
|
||||
// remove outgoing cfg edges of the old node
|
||||
|
@ -333,6 +339,7 @@ public class ClosureExtractor extends CAstRewriterExt {
|
|||
CAstNode retval = copyNodes(root.getChild(0), cfg, new ChildPos(root, 0, context), nodeMap);
|
||||
CAstNode newNode =
|
||||
Ast.makeNode(RETURN,
|
||||
addNode(
|
||||
Ast.makeNode(OBJECT_LITERAL,
|
||||
addExnFlow(Ast.makeNode(CALL,
|
||||
addExnFlow(makeVarRef("Object"), JavaScriptTypes.ReferenceError, getCurrentEntity(), context),
|
||||
|
@ -340,19 +347,23 @@ public class ClosureExtractor extends CAstRewriterExt {
|
|||
Ast.makeConstant("type"),
|
||||
Ast.makeConstant("return"),
|
||||
Ast.makeConstant("value"),
|
||||
retval));
|
||||
retval),
|
||||
getCurrentEntity().getControlFlow()));
|
||||
nodeMap.put(Pair.make(root, context.key()), newNode);
|
||||
return newNode;
|
||||
} else {
|
||||
// return { type: 'return' }
|
||||
CAstNode newNode =
|
||||
Ast.makeNode(RETURN,
|
||||
addNode(
|
||||
Ast.makeNode(OBJECT_LITERAL,
|
||||
addExnFlow(Ast.makeNode(CALL,
|
||||
addExnFlow(makeVarRef("Object"), JavaScriptTypes.ReferenceError, getCurrentEntity(), context),
|
||||
Ast.makeConstant("ctor")), null, getCurrentEntity(), context),
|
||||
Ast.makeConstant("type"),
|
||||
Ast.makeConstant("return")));
|
||||
Ast.makeConstant("return")),
|
||||
getCurrentEntity().getControlFlow()));
|
||||
|
||||
nodeMap.put(Pair.make(root, context.key()), newNode);
|
||||
return newNode;
|
||||
}
|
||||
|
|
|
@ -1236,12 +1236,22 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
public void action(AbstractFieldPointerKey fieldKey) {
|
||||
if (!representsNullType(fieldKey.getInstanceKey())) {
|
||||
system.newConstraint(lhs, assignOperator, fieldKey);
|
||||
AbstractFieldPointerKey unknown = getBuilder().fieldKeyForUnknownWrites(fieldKey);
|
||||
if (unknown != null) {
|
||||
system.newConstraint(lhs, assignOperator, unknown);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
*
|
||||
* Is definingMethod the same as the method represented by opNode? We need this since the names for
|
||||
|
|
|
@ -8,7 +8,7 @@ Require-Bundle: com.ibm.wala.shrike,
|
|||
com.ibm.wala.core,
|
||||
org.eclipse.core.runtime,
|
||||
com.ibm.wala.core.testdata;bundle-version="1.3.4",
|
||||
org.junit;bundle-version="4.11.0"
|
||||
org.junit;bundle-version="4.0.0"
|
||||
Bundle-Localization: plugin
|
||||
Export-Package: com.ibm.wala.core.tests.basic,
|
||||
com.ibm.wala.core.tests.callGraph,
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.cfg;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.shrikeBT.ExceptionHandler;
|
||||
|
||||
public interface BytecodeCFG {
|
||||
|
||||
public Set<ExceptionHandler> getExceptionHandlers();
|
||||
|
||||
}
|
|
@ -41,7 +41,7 @@ import com.ibm.wala.util.warnings.Warnings;
|
|||
/**
|
||||
* A graph of basic blocks.
|
||||
*/
|
||||
public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> {
|
||||
public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> implements BytecodeCFG {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
|
@ -513,6 +513,7 @@ public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> {
|
|||
return s.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ExceptionHandler> getExceptionHandlers() {
|
||||
return exceptionHandlers;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public interface PointerAnalysis<T extends InstanceKey> {
|
|||
* @return the bijection between InstanceKey <=> Integer that defines the
|
||||
* interpretation of points-to-sets.
|
||||
*/
|
||||
OrdinalSetMapping<InstanceKey> getInstanceKeyMapping();
|
||||
OrdinalSetMapping<T> getInstanceKeyMapping();
|
||||
|
||||
/**
|
||||
* @return all pointer keys known
|
||||
|
@ -54,7 +54,7 @@ public interface PointerAnalysis<T extends InstanceKey> {
|
|||
/**
|
||||
* @return all instance keys known
|
||||
*/
|
||||
Collection<InstanceKey> getInstanceKeys();
|
||||
Collection<T> getInstanceKeys();
|
||||
|
||||
/**
|
||||
* did the pointer analysis use a type filter for a given points-to set?
|
||||
|
|
|
@ -17,7 +17,7 @@ import com.ibm.wala.ipa.callgraph.propagation.ReturnValueKey;
|
|||
* A key which represents the return value for a node.
|
||||
*/
|
||||
public final class ExceptionReturnValueKey extends ReturnValueKey {
|
||||
ExceptionReturnValueKey(CGNode node) {
|
||||
public ExceptionReturnValueKey(CGNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,10 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.cfg.BytecodeCFG;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.cfg.InducedCFG;
|
||||
import com.ibm.wala.cfg.ShrikeCFG;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
|
@ -107,8 +107,8 @@ public class SSACFG implements ControlFlowGraph<SSAInstruction, ISSABasicBlock>
|
|||
addPhisFromInducedCFG((InducedCFG) cfg);
|
||||
addPisFromInducedCFG((InducedCFG) cfg);
|
||||
}
|
||||
if (cfg instanceof ShrikeCFG) {
|
||||
recordExceptionTypes(((ShrikeCFG) cfg).getExceptionHandlers(), method.getDeclaringClass().getClassLoader());
|
||||
if (cfg instanceof BytecodeCFG) {
|
||||
recordExceptionTypes(((BytecodeCFG) cfg).getExceptionHandlers(), method.getDeclaringClass().getClassLoader());
|
||||
}
|
||||
this.instructions = instructions;
|
||||
|
||||
|
|
|
@ -11,6 +11,6 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
com.ibm.wala.dalvik;bundle-version="1.0.0",
|
||||
com.ibm.wala.core;bundle-version="1.3.4",
|
||||
com.ibm.wala.shrike;bundle-version="1.3.4",
|
||||
org.junit;bundle-version="4.11.0"
|
||||
org.junit;bundle-version="4.0.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.ibm.wala.dalvik.drivers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.ibm.wala.dalvik.test.callGraph.DalvikCallGraphTestBase;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
@ -11,12 +12,43 @@ import com.ibm.wala.util.CancelException;
|
|||
public class APKCallGraphDriver {
|
||||
|
||||
public static void main(String[] args) throws ClassHierarchyException, IllegalArgumentException, IOException, CancelException {
|
||||
CallGraph CG = DalvikCallGraphTestBase.makeAPKCallGraph(args[0]).fst;
|
||||
System.err.println(CG);
|
||||
File apk = new File(args[0]);
|
||||
recurseApks(apk);
|
||||
}
|
||||
|
||||
protected static void recurseApks(File apk) throws IOException,
|
||||
ClassHierarchyException, CancelException {
|
||||
if (apk.isDirectory()) {
|
||||
for(File f : apk.listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith("apk") || new File(dir, name).isDirectory();
|
||||
}
|
||||
})) {
|
||||
recurseApks(f);
|
||||
}
|
||||
} else {
|
||||
doApk(apk);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void doApk(File apk) throws IOException,
|
||||
ClassHierarchyException, CancelException {
|
||||
System.err.println("Analyzing " + apk + "...");
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
CallGraph CG = DalvikCallGraphTestBase.makeAPKCallGraph(apk.getAbsolutePath()).fst;
|
||||
System.err.println("Analyzed " + apk + " in " + (System.currentTimeMillis() - time));
|
||||
System.err.println(CG);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
/*
|
||||
for(CGNode n : CG) {
|
||||
System.err.println(n);
|
||||
System.err.println(n.getIR());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ import com.ibm.wala.ipa.callgraph.impl.Util;
|
|||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ReturnValueKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.ExceptionReturnValueKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
|
@ -84,15 +86,15 @@ public class JVMLDalvikComparison extends DalvikCallGraphTestBase {
|
|||
Set<MethodReference> androidMethods = applicationMethods(android.fst);
|
||||
Set<MethodReference> javaMethods = applicationMethods(java.fst);
|
||||
|
||||
if (!androidMethods.containsAll(javaMethods)) {
|
||||
Set<MethodReference> androidExtra = HashSetFactory.make(androidMethods);
|
||||
androidExtra.removeAll(javaMethods);
|
||||
Set<MethodReference> javaExtra = HashSetFactory.make(javaMethods);
|
||||
javaExtra.removeAll(androidMethods);
|
||||
|
||||
System.err.println(edgeDiff(java.fst, android.fst));
|
||||
System.err.println(javaExtra);
|
||||
Set<Pair<CGNode, CGNode>> javaExtraEdges = edgeDiff(java.fst, android.fst);
|
||||
|
||||
if (!javaExtraEdges.isEmpty()) {
|
||||
Set<MethodReference> javaExtraNodes = HashSetFactory.make(javaMethods);
|
||||
javaExtraNodes.removeAll(androidMethods);
|
||||
|
||||
System.err.println(javaExtraEdges);
|
||||
System.err.println(javaExtraNodes);
|
||||
|
||||
System.err.println(android.fst);
|
||||
|
||||
for(CGNode n : android.fst) {
|
||||
|
@ -100,6 +102,8 @@ public class JVMLDalvikComparison extends DalvikCallGraphTestBase {
|
|||
if (n.getIR() != null) {
|
||||
System.err.println(n.getIR());
|
||||
|
||||
System.err.println("return: " + android.snd.getPointsToSet(new ReturnValueKey(n)));
|
||||
System.err.println("exceptions: " + android.snd.getPointsToSet(new ExceptionReturnValueKey(n)));
|
||||
for(int i = 1; i < n.getIR().getSymbolTable().getMaxValueNumber(); i++) {
|
||||
LocalPointerKey x = new LocalPointerKey(n, i);
|
||||
OrdinalSet<InstanceKey> s = android.snd.getPointsToSet(x);
|
||||
|
@ -111,7 +115,7 @@ public class JVMLDalvikComparison extends DalvikCallGraphTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue(androidMethods.containsAll(javaMethods));
|
||||
Assert.assertTrue(javaExtraEdges.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.cfg.BytecodeCFG;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.classLoader.BytecodeLanguage;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
|
@ -43,15 +44,14 @@ import com.ibm.wala.util.collections.ArrayIterator;
|
|||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.impl.NodeWithNumber;
|
||||
import com.ibm.wala.util.intset.BitVector;
|
||||
import com.ibm.wala.util.shrike.ShrikeUtil;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
import com.ibm.wala.util.warnings.Warnings;
|
||||
|
||||
public class DexCFG extends AbstractCFG<Instruction, DexCFG.BasicBlock>{
|
||||
public class DexCFG extends AbstractCFG<Instruction, DexCFG.BasicBlock> implements BytecodeCFG {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DexCFG.class);
|
||||
|
||||
//public class ShrikeCFG extends AbstractCFG<IInstruction, ShrikeCFG.BasicBlock> {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private int[] instruction2Block;
|
||||
|
@ -664,9 +664,14 @@ public class DexCFG extends AbstractCFG<Instruction, DexCFG.BasicBlock>{
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer("");
|
||||
BitVector catches = this.getCatchBlocks();
|
||||
for (Iterator<BasicBlock> it = iterator(); it.hasNext();) {
|
||||
BasicBlock bb = it.next();
|
||||
s.append("BB").append(getNumber(bb)).append("\n");
|
||||
s.append("BB").append(getNumber(bb));
|
||||
if (catches.contains(bb.getNumber())) {
|
||||
s.append("<Handler>");
|
||||
}
|
||||
s.append("\n");
|
||||
for (int j = bb.getFirstInstructionIndex(); j <= bb.getLastInstructionIndex(); j++) {
|
||||
s.append(" ").append(j).append(" ").append(getInstructions()[j]).append("\n");
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import com.ibm.wala.cast.ir.ssa.AstConstants;
|
|||
import com.ibm.wala.dalvik.classLoader.DexIMethod;
|
||||
import com.ibm.wala.shrikeBT.IUnaryOpInstruction;
|
||||
import com.ibm.wala.shrikeBT.IUnaryOpInstruction.IOperator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
public class UnaryOperation extends Instruction {
|
||||
|
||||
|
@ -116,10 +117,6 @@ public class UnaryOperation extends Instruction {
|
|||
public IOperator getOperator() {
|
||||
switch(op)
|
||||
{
|
||||
// moves
|
||||
case MOVE:
|
||||
case MOVE_WIDE:
|
||||
return null;
|
||||
// SSA unary ops
|
||||
case NOT:
|
||||
return AstConstants.UnaryOp.BITNOT;
|
||||
|
@ -135,24 +132,8 @@ public class UnaryOperation extends Instruction {
|
|||
return IUnaryOpInstruction.Operator.NEG;
|
||||
case NEGDOUBLE:
|
||||
return IUnaryOpInstruction.Operator.NEG;
|
||||
// SSA conversions
|
||||
case DOUBLETOLONG:
|
||||
case DOUBLETOFLOAT:
|
||||
case INTTOBYTE:
|
||||
case INTTOCHAR:
|
||||
case INTTOSHORT:
|
||||
case DOUBLETOINT:
|
||||
case FLOATTODOUBLE:
|
||||
case FLOATTOLONG:
|
||||
case FLOATTOINT:
|
||||
case LONGTODOUBLE:
|
||||
case LONGTOFLOAT:
|
||||
case LONGTOINT:
|
||||
case INTTODOUBLE:
|
||||
case INTTOFLOAT:
|
||||
case INTTOLONG:
|
||||
return null;
|
||||
default:
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -339,24 +339,6 @@ public abstract class AbstractIntRegisterMachine implements FixedPointConstants
|
|||
*/
|
||||
protected interface Meeter {
|
||||
|
||||
/**
|
||||
* Return the integer that represents the meet of a particular stack slot at the entry to a basic block.
|
||||
*
|
||||
* @param slot The stack slot to meet
|
||||
* @param rhs The values to meet
|
||||
* @param bb The basic block at whose entry this meet occurs
|
||||
* @return The value result of the meet
|
||||
*/
|
||||
// int meetStack(int slot, int[] rhs, IBasicBlock<Instruction> bb);
|
||||
|
||||
/**
|
||||
* Return the integer that represents stack slot 0 after a meet at the entry to a catch block.
|
||||
*
|
||||
* @param bb The basic block at whose entry this meet occurs
|
||||
* @return The value of stack slot 0 after the meet
|
||||
*/
|
||||
int meetStackAtCatchBlock(BasicBlock bb);
|
||||
|
||||
/**
|
||||
* Return the integer that represents the meet of a particular local at the entry to a basic block.
|
||||
*
|
||||
|
@ -394,55 +376,13 @@ public abstract class AbstractIntRegisterMachine implements FixedPointConstants
|
|||
*/
|
||||
private boolean meetForCatchBlock(IVariable lhs, IVariable[] rhs, BasicBlock bb, Meeter meeter) {
|
||||
|
||||
//TODO: do we need to check the meet of the catch block? possibly compare the value of meet with the symboltable values of the exception registers?
|
||||
boolean changed = meetRegistersAtCatchBlock(lhs, bb, meeter);
|
||||
|
||||
changed |= meetLocals(lhs, rhs, bb, meeter);
|
||||
boolean changed = meetLocals(lhs, rhs, bb, meeter);
|
||||
|
||||
// int meet = meeter.meetStackAtCatchBlock(bb);
|
||||
// boolean changed = meetLocals(lhs, rhs, bb, meeter);
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a meet of the registers of machine states at the entry of a catch block.
|
||||
*
|
||||
* TODO: add some efficiency shortcuts. TODO: clean up and refactor.
|
||||
*
|
||||
* @param bb the basic block at whose entry the meet occurs
|
||||
* @return true if the lhs value changes. false otherwise.
|
||||
*/
|
||||
private boolean meetRegistersAtCatchBlock(IVariable lhs, BasicBlock bb, Meeter meeter) {
|
||||
boolean changed = false;
|
||||
MachineState L = (MachineState) lhs;
|
||||
|
||||
// evaluate the meet of the stack of height 1, which holds the exception
|
||||
// object.
|
||||
|
||||
// allocate lhs registers if it's
|
||||
// not already allocated.
|
||||
if (L.locals == null) {
|
||||
L.allocateLocals();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
DexIMethod dMethod = (DexIMethod)L.getBasicBlock().getMethod();
|
||||
//System.out.println("dMethod local size: " + dMethod.getExceptionReg() + " - local size: " + L.locals.length);
|
||||
assert(L.locals.length == dMethod.getExceptionReg()+1);
|
||||
for (int i = 0; i < L.locals.length; i++)
|
||||
logger.debug("local: " + L.locals[i]);
|
||||
|
||||
int meet = meeter.meetStackAtCatchBlock(bb);
|
||||
if (L.locals[dMethod.getExceptionReg()] == TOP) {
|
||||
changed = true;
|
||||
L.locals[dMethod.getExceptionReg()] = meet;
|
||||
} else if (meet != L.locals[dMethod.getExceptionReg()]) {
|
||||
changed = true;
|
||||
L.locals[dMethod.getExceptionReg()] = meet;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate a meet of the stacks of machine states at the entry of a catch block.
|
||||
*
|
||||
|
|
|
@ -142,7 +142,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
boolean buildLocalMap, SSAPiNodePolicy piNodePolicy) {
|
||||
super(scfg);
|
||||
localMap = buildLocalMap ? new SSA2LocalMap(scfg, instructions.length, cfg.getNumberOfNodes(), method.getMaxLocals()) : null;
|
||||
init(new SymbolTableMeeter(symbolTable, cfg, instructions, scfg), new SymbolicPropagator(scfg, instructions, symbolTable,
|
||||
init(new SymbolTableMeeter(cfg, instructions, scfg), new SymbolicPropagator(scfg, instructions,
|
||||
localMap, cfg, piNodePolicy));
|
||||
this.method = method;
|
||||
this.symbolTable = symbolTable;
|
||||
|
@ -156,16 +156,11 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
|
||||
final SSACFG cfg;
|
||||
|
||||
// final SSAInstruction[] instructions;
|
||||
|
||||
final SymbolTable symbolTable;
|
||||
|
||||
final DexCFG dexCFG;
|
||||
|
||||
SymbolTableMeeter(SymbolTable symbolTable, SSACFG cfg, SSAInstruction[] instructions, DexCFG dexCFG) {
|
||||
SymbolTableMeeter(SSACFG cfg, SSAInstruction[] instructions, DexCFG dexCFG) {
|
||||
this.cfg = cfg;
|
||||
// this.instructions = instructions;
|
||||
this.symbolTable = symbolTable;
|
||||
this.dexCFG = dexCFG;
|
||||
}
|
||||
|
||||
|
@ -263,28 +258,6 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.analysis.stackMachine.AbstractIntStackMachine.Meeter#meetStackAtCatchBlock(BasicBlock)
|
||||
*/
|
||||
public int meetStackAtCatchBlock(BasicBlock bb) {
|
||||
int bbNumber = dexCFG.getNumber(bb);
|
||||
SSACFG.ExceptionHandlerBasicBlock newBB = (SSACFG.ExceptionHandlerBasicBlock) cfg.getNode(bbNumber);
|
||||
SSAGetCaughtExceptionInstruction s = newBB.getCatchInstruction();
|
||||
int exceptionValue;
|
||||
if (cfg.getMethod().getReference().toString().equals("< Application, Lcom/google/android/gms/tagmanager/v$a, onOpen(Landroid/database/sqlite/SQLiteDatabase;)V >")) {
|
||||
System.err.println("got here");
|
||||
}
|
||||
if (s == null) {
|
||||
exceptionValue = symbolTable.newSymbol();
|
||||
s = insts.GetCaughtExceptionInstruction(bb.getLastInstructionIndex(), bbNumber, exceptionValue);
|
||||
newBB.setCatchInstruction(s);
|
||||
} else {
|
||||
exceptionValue = s.getException();
|
||||
}
|
||||
return exceptionValue;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -363,8 +336,6 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
|
||||
final SSAInstruction[] instructions;
|
||||
|
||||
final SymbolTable symbolTable;
|
||||
|
||||
final DexCFG dexCFG;
|
||||
|
||||
final SSACFG cfg;
|
||||
|
@ -380,7 +351,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
|
||||
final SSAPiNodePolicy piNodePolicy;
|
||||
|
||||
public SymbolicPropagator(DexCFG dexCFG, SSAInstruction[] instructions, SymbolTable symbolTable, SSA2LocalMap localMap,
|
||||
public SymbolicPropagator(DexCFG dexCFG, SSAInstruction[] instructions, SSA2LocalMap localMap,
|
||||
SSACFG cfg, SSAPiNodePolicy piNodePolicy) {
|
||||
super(dexCFG);
|
||||
this.piNodePolicy = null;// piNodePolicy;
|
||||
|
@ -388,7 +359,6 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
this.creators = new SSAInstruction[0];
|
||||
this.dexCFG = dexCFG;
|
||||
this.instructions = instructions;
|
||||
this.symbolTable = symbolTable;
|
||||
this.loader = dexCFG.getMethod().getDeclaringClass().getClassLoader().getReference();
|
||||
// this.localMap = localMap;
|
||||
init(this.new NodeVisitor(cfg), this.new EdgeVisitor());
|
||||
|
@ -469,7 +439,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
int arrayRef = workingState.getLocal(instruction.source);
|
||||
int dest = instruction.destination;
|
||||
int length = reuseOrCreateDef();
|
||||
workingState.setLocal(dest, length);
|
||||
setLocal(dest, length);
|
||||
|
||||
emitInstruction(insts.ArrayLengthInstruction(getCurrentInstructionIndex(), length, arrayRef));
|
||||
}
|
||||
|
@ -485,7 +455,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
// int index = workingState.pop();
|
||||
// int arrayRef = workingState.pop();
|
||||
int result = reuseOrCreateDef();
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
TypeReference t = instruction.getType();
|
||||
// if (instruction.isAddressOf()) {
|
||||
|
@ -580,7 +550,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
// int val2 = workingState.pop();
|
||||
// int val1 = workingState.pop();
|
||||
int result = reuseOrCreateDef();
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
// boolean isFloat = instruction.getType().equals(TYPE_double) || instruction.getType().equals(TYPE_float);
|
||||
emitInstruction(insts.BinaryOpInstruction(getCurrentInstructionIndex(), instruction.getOperator(), false, instruction.isUnsigned(), result, val1, val2, !instruction.isFloat()));
|
||||
|
@ -611,7 +581,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
// int val2 = workingState.pop();
|
||||
// int val1 = workingState.pop();
|
||||
int result = reuseOrCreateDef();
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
// boolean isFloat = instruction.getType().equals(TYPE_double) || instruction.getType().equals(TYPE_float);
|
||||
try {
|
||||
|
@ -625,6 +595,11 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
}
|
||||
}
|
||||
|
||||
protected void setLocal(int dest, int result) {
|
||||
assert result <= symbolTable.getMaxValueNumber();
|
||||
workingState.setLocal(dest, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.shrikeBT.Instruction.Visitor#visitCheckCast(CheckCastInstruction)
|
||||
*/
|
||||
|
@ -705,7 +680,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
{
|
||||
Assertions.UNREACHABLE("unexpected constant instruction " + instruction);
|
||||
}
|
||||
workingState.setLocal(dest, symbol);
|
||||
setLocal(dest, symbol);
|
||||
// Language l = cfg.getMethod().getDeclaringClass().getClassLoader().getLanguage();
|
||||
// TypeReference type = l.getConstantType(instruction.getValue());
|
||||
// int symbol = 0;
|
||||
|
@ -785,7 +760,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
// int ref = workingState.pop();
|
||||
// emitInstruction(insts.GetInstruction(result, ref, f));
|
||||
// }
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
}
|
||||
|
||||
|
@ -806,7 +781,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
int dest = instruction.destination;
|
||||
// int ref = workingState.pop();
|
||||
int result = reuseOrCreateDef();
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
// TypeReference t = ShrikeUtil.makeTypeReference(loader, instruction.getType());
|
||||
emitInstruction(insts.InstanceofInstruction(getCurrentInstructionIndex(), result, ref, instruction.type));
|
||||
|
@ -851,7 +826,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
IInvokeInstruction.IDispatch code = instruction.getInvocationCode();
|
||||
CallSiteReference site = CallSiteReference.make(getCurrentProgramCounter(), m, code);
|
||||
int exc = reuseOrCreateException();
|
||||
workingState.setLocal(dexCFG.getDexMethod().getExceptionReg(), exc);
|
||||
setLocal(dexCFG.getDexMethod().getExceptionReg(), exc);
|
||||
|
||||
|
||||
int n = instruction.args.length;
|
||||
|
@ -903,7 +878,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
// int dest = dexCFG.getDexMethod().regBank.getReturnReg().regID;
|
||||
int dest = dexCFG.getDexMethod().getReturnReg();
|
||||
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
SSAInstruction inst = insts.InvokeInstruction(getCurrentInstructionIndex(), result, params, exc, site);
|
||||
//System.out.println("Emitting(2) InvokeInstruction: "+inst);
|
||||
emitInstruction(inst);
|
||||
|
@ -980,7 +955,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
emitInstruction(insts.NewInstruction(getCurrentInstructionIndex(), result, instruction.newSiteRef));
|
||||
// popN(instruction);
|
||||
// }
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
}
|
||||
|
||||
|
@ -995,7 +970,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
sizes[i] = workingState.getLocal(instruction.sizes[i]);
|
||||
}
|
||||
emitInstruction(insts.NewInstruction(getCurrentInstructionIndex(), result, instruction.newSiteRef, sizes));
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1009,7 +984,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
sizes[i] = symbolTable.getConstant(instruction.sizes[i]);
|
||||
}
|
||||
emitInstruction(insts.NewInstruction(getCurrentInstructionIndex(), result, instruction.newSiteRef, sizes));
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
|
||||
for (int i = 0; i < instruction.args.length; i++)
|
||||
{
|
||||
|
@ -1143,6 +1118,7 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
@Override
|
||||
public void visitThrow(Throw instruction) {
|
||||
int throwable = workingState.getLocal(instruction.throwable);
|
||||
assert symbolTable.getMaxValueNumber() >= throwable;
|
||||
emitInstruction(insts.ThrowInstruction(getCurrentInstructionIndex(), throwable));
|
||||
// if (instruction.isRethrow()) {
|
||||
// workingState.clearStack();
|
||||
|
@ -1160,12 +1136,33 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
*/
|
||||
@Override
|
||||
public void visitUnaryOperation(UnaryOperation instruction) {
|
||||
|
||||
if (instruction.op == UnaryOperation.OpID.MOVE_EXCEPTION) {
|
||||
|
||||
int idx = getCurrentInstructionIndex();
|
||||
int bbidx = dexCFG.getBlockForInstruction(idx).getNumber();
|
||||
ExceptionHandlerBasicBlock newBB = (ExceptionHandlerBasicBlock) cfg.getBasicBlock(bbidx);
|
||||
|
||||
SSAGetCaughtExceptionInstruction s = newBB.getCatchInstruction();
|
||||
int exceptionValue;
|
||||
if (s == null) {
|
||||
exceptionValue = symbolTable.newSymbol();
|
||||
s = insts.GetCaughtExceptionInstruction(newBB.getLastInstructionIndex(), bbidx, exceptionValue);
|
||||
newBB.setCatchInstruction(s);
|
||||
} else {
|
||||
exceptionValue = s.getException();
|
||||
}
|
||||
|
||||
setLocal(instruction.destination, exceptionValue);
|
||||
return;
|
||||
}
|
||||
|
||||
//System.out.println("Instruction: " + getCurrentInstructionIndex());
|
||||
int val = workingState.getLocal(instruction.source);
|
||||
// int val = workingState.pop();
|
||||
int dest = instruction.destination;
|
||||
int result = reuseOrCreateDef();
|
||||
workingState.setLocal(dest, result);
|
||||
setLocal(dest, result);
|
||||
// workingState.push(result);
|
||||
if(instruction.isConversion())
|
||||
{
|
||||
|
@ -1238,25 +1235,20 @@ public class DexSSABuilder extends AbstractIntRegisterMachine {
|
|||
throw new IllegalArgumentException("unknown conversion type "+instruction.op+" in unary instruction: "+instruction);
|
||||
}
|
||||
emitInstruction(insts.ConversionInstruction(getCurrentInstructionIndex(), result, val, fromType, toType, overflows));
|
||||
}
|
||||
else if (instruction.op == UnaryOperation.OpID.MOVE_EXCEPTION) {
|
||||
int source = ((DexIMethod)dexCFG.getMethod()).getExceptionReg();
|
||||
workingState.setLocal(instruction.destination, source);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
emitInstruction(insts.UnaryOpInstruction(getCurrentInstructionIndex(), instruction.getOperator(), result, val));
|
||||
// emitInstruction(insts.UnaryOpInstruction(getCurrentInstructionIndex(), instruction.getOperator(), result, val));
|
||||
|
||||
if (instruction.op == UnaryOperation.OpID.MOVE) {
|
||||
workingState.setLocal(instruction.destination, workingState.getLocal(instruction.source));
|
||||
setLocal(instruction.destination, workingState.getLocal(instruction.source));
|
||||
}
|
||||
else if (instruction.op == UnaryOperation.OpID.MOVE_WIDE) {
|
||||
workingState.setLocal(instruction.destination, workingState.getLocal(instruction.source));
|
||||
setLocal(instruction.destination, workingState.getLocal(instruction.source));
|
||||
if (instruction.source == dexCFG.getDexMethod().getReturnReg())
|
||||
workingState.setLocal(instruction.destination+1, workingState.getLocal(instruction.source));
|
||||
setLocal(instruction.destination+1, workingState.getLocal(instruction.source));
|
||||
else
|
||||
workingState.setLocal(instruction.destination+1, workingState.getLocal(instruction.source+1));
|
||||
setLocal(instruction.destination+1, workingState.getLocal(instruction.source+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ Require-Bundle: com.ibm.wala.cast.java.test;bundle-version="1.0.0",
|
|||
com.ibm.wala.util;bundle-version="1.1.3",
|
||||
org.eclipse.core.resources;bundle-version="3.4.1",
|
||||
org.eclipse.jdt.core;bundle-version="3.4.2",
|
||||
org.junit;bundle-version="4.8.1",
|
||||
org.junit;bundle-version="4.0.0",
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.pde.core;bundle-version="3.6.0",
|
||||
org.eclipse.platform;bundle-version="4.2.2"
|
||||
|
|
|
@ -440,13 +440,13 @@ public class FakeExceptionTypeBinding implements ITypeBinding {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
// do not put @Override here, to avoid breaking compilation on Juno
|
||||
public IMethodBinding getFunctionalInterfaceMethod() {
|
||||
Assertions.UNREACHABLE("FakeExceptionTypeBinding ");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
// do not put @Override here, to avoid breaking compilation on Juno
|
||||
public IAnnotationBinding[] getTypeAnnotations() {
|
||||
Assertions.UNREACHABLE("FakeExceptionTypeBinding ");
|
||||
return null;
|
||||
|
|
|
@ -99,11 +99,6 @@ public class JavaEclipseProjectPath extends EclipseProjectPath<IClasspathEntry,
|
|||
}
|
||||
case IClasspathEntry.CPE_CONTAINER: {
|
||||
try {
|
||||
|
||||
for(IClasspathEntry x : JavaCore.getClasspathContainer(JavaRuntime.getDefaultJREContainerEntry().getPath(), project).getClasspathEntries()) {
|
||||
System.err.println("xxx " + x);
|
||||
}
|
||||
|
||||
IClasspathContainer cont = JavaCore.getClasspathContainer(entry.getPath(), project);
|
||||
IClasspathEntry[] entries = cont.getClasspathEntries();
|
||||
resolveClasspathEntries(project, Arrays.asList(entries), cont.getKind() == IClasspathContainer.K_APPLICATION ? loader : Loader.PRIMORDIAL,
|
||||
|
|
|
@ -9,15 +9,16 @@ Require-Bundle: com.ibm.wala.core;bundle-version="1.1.3",
|
|||
com.ibm.wala.cast.js.rhino;bundle-version="1.0.0",
|
||||
com.ibm.wala.ide;bundle-version="1.3.4",
|
||||
com.ibm.wala.ide.jsdt;bundle-version="1.0.0",
|
||||
org.eclipse.wst.jsdt.core,
|
||||
org.eclipse.equinox.common;bundle-version="3.6.100",
|
||||
com.ibm.wala.ide.tests;bundle-version="1.1.3",
|
||||
org.eclipse.core.runtime;bundle-version="3.8.0",
|
||||
org.eclipse.wst.jsdt.ui;bundle-version="1.1.0",
|
||||
org.eclipse.wst.jsdt.core;bundle-version="1.1.0",
|
||||
org.junit;bundle-version="4.0.0",
|
||||
org.eclipse.ui;bundle-version="3.104.0",
|
||||
org.eclipse.ui.ide;bundle-version="3.8.2",
|
||||
org.eclipse.pde;bundle-version="3.8.0",
|
||||
org.eclipse.pde.core;bundle-version="3.8.1"
|
||||
org.eclipse.pde.core;bundle-version="3.8.1",
|
||||
org.eclipse.equinox.common;bundle-version="3.6.100",
|
||||
org.eclipse.core.runtime;bundle-version="3.8.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-Activator: com.ibm.wala.ide.jsdt.tests.Activator
|
||||
Export-Package: com.ibm.wala.ide.jsdt.tests
|
||||
|
|
|
@ -40,7 +40,7 @@ import com.ibm.wala.util.CancelException;
|
|||
import com.ibm.wala.util.collections.Pair;
|
||||
|
||||
public abstract class AbstractJSProjectScopeTest {
|
||||
|
||||
|
||||
protected final ZippedProjectData project;
|
||||
|
||||
public AbstractJSProjectScopeTest(ZippedProjectData project) {
|
||||
|
@ -68,7 +68,7 @@ public abstract class AbstractJSProjectScopeTest {
|
|||
return JavaScriptEclipseProjectPath.make(p, Collections.<Pair<String,Plugin>>emptySet());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Ignore("works for me on luna, but ignored for now to avoid breaking juno")
|
||||
@Test
|
||||
public void testParsing() throws IOException, CoreException {
|
||||
Set<ModuleEntry> mes = JsdtUtil.getJavaScriptCodeFromProject(project.projectName);
|
||||
|
@ -77,9 +77,7 @@ public abstract class AbstractJSProjectScopeTest {
|
|||
System.err.println(info.calls.size());
|
||||
System.err.println("call graph:\n" + info.cg);
|
||||
Assert.assertTrue("cannot find any function calls", info.calls.size()>0);
|
||||
|
||||
// JSDT call graph builder seems to have changed, and I no longer get any nodes
|
||||
// Assert.assertTrue("cannot find any cg nodes", info.cg.getNumberOfNodes()>0);
|
||||
Assert.assertTrue("cannot find any cg nodes", info.cg.getNumberOfNodes()>0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.eclipse.core.resources.ResourcesPlugin;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.jdt.core.IClasspathEntry;
|
||||
import org.eclipse.jdt.internal.core.ClasspathEntry;
|
||||
import org.eclipse.osgi.service.resolver.BundleDescription;
|
||||
import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
|
||||
import org.eclipse.pde.core.plugin.IPluginModelBase;
|
||||
|
@ -286,6 +285,7 @@ public abstract class EclipseProjectPath<E, P> {
|
|||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void resolveClasspathEntries(P project, List l, ILoader loader, boolean includeSource, boolean entriesFromTopLevelProject) {
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
resolveClasspathEntry(project, resolve((E)l.get(i)), loader, includeSource, entriesFromTopLevelProject);
|
||||
|
|
|
@ -52,10 +52,12 @@ public class ProgressMonitorDelegate implements IProgressMonitor {
|
|||
}
|
||||
|
||||
/** BEGIN Custom change: subtasks and canceling */
|
||||
@Override
|
||||
public void subTask(String subTask) {
|
||||
delegate.subTask(subTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
delegate.setCanceled(true);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ public class DynamicCallGraph {
|
|||
}
|
||||
}
|
||||
|
||||
instrumenter = new OfflineInstrumenter(!patchExits);
|
||||
instrumenter = new OfflineInstrumenter(true);
|
||||
args = instrumenter.parseStandardArgs(args);
|
||||
|
||||
instrumenter.setPassUnmodifiedClasses(true);
|
||||
|
|
|
@ -517,6 +517,7 @@ public abstract class ConstantInstruction extends Instruction {
|
|||
// load of a class constant may trigger a ClassNotFoundException
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final static class LazyClass extends ConstClass {
|
||||
|
|
|
@ -226,6 +226,10 @@ public class Analyzer {
|
|||
|
||||
String x = ClassHierarchy.findCommonSupertype(hierarchy, patchType(t1), patchType(t2));
|
||||
|
||||
if (String.valueOf(t1).contains("groovy/lang/GroovyObject") || String.valueOf(t2).contains("groovy/lang/GroovyObject")) {
|
||||
System.err.println(t1 + " -- " + t2 + " --> " + x);
|
||||
}
|
||||
|
||||
if ("L?;".equals(x)) {
|
||||
System.err.println(t1 + " -- " + t2);
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ public final class ClassHierarchy {
|
|||
if (t2.equals(Constants.TYPE_Object)) {
|
||||
return YES;
|
||||
} else {
|
||||
int v = checkSupertypesContain(hierarchy, t1, t2);
|
||||
int v = checkSupertypesContain(hierarchy, t1, t2);
|
||||
if (v == MAYBE) {
|
||||
v = checkSubtypesContain(hierarchy, t2, t1, new HashSet<String>());
|
||||
}
|
||||
|
@ -276,12 +276,7 @@ public final class ClassHierarchy {
|
|||
return r;
|
||||
}
|
||||
|
||||
private static String findCommonSupertypeHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) {
|
||||
|
||||
if (hierarchy != null && t1.contains("Reader") && t2.contains("Reader")) {
|
||||
System.err.println("got here");
|
||||
}
|
||||
|
||||
private static String findCommonSupertypeHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) {
|
||||
if (isSubtypeOf(hierarchy, t1, t2) == YES) {
|
||||
return t2;
|
||||
} else if (isSubtypeOf(hierarchy, t2, t1) == YES) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.ibm.wala.shrikeBT.IShiftInstruction;
|
|||
import com.ibm.wala.shrikeBT.IStoreInstruction;
|
||||
import com.ibm.wala.shrikeBT.ITypeTestInstruction;
|
||||
import com.ibm.wala.shrikeBT.IUnaryOpInstruction;
|
||||
import com.ibm.wala.shrikeBT.InvokeDynamicInstruction;
|
||||
import com.ibm.wala.shrikeBT.MethodData;
|
||||
import com.ibm.wala.shrikeBT.MonitorInstruction;
|
||||
import com.ibm.wala.shrikeBT.NewInstruction;
|
||||
|
@ -231,6 +232,10 @@ public final class Verifier extends Analyzer {
|
|||
|
||||
@Override
|
||||
public void visitInvoke(IInvokeInstruction instruction) {
|
||||
if (instruction instanceof InvokeDynamicInstruction) {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure constant pool entries are dereferenced
|
||||
String classType = instruction.getClassType();
|
||||
String signature = instruction.getMethodSignature();
|
||||
|
|
|
@ -423,12 +423,9 @@ final public class ClassInstrumenter {
|
|||
codeAttrCount++;
|
||||
}
|
||||
if (oldCode.getClassReader().getMajorVersion() > 50) {
|
||||
try { /*
|
||||
try {
|
||||
List<StackMapFrame> sm = StackMapTableReader.readStackMap(oldCode);
|
||||
if (sm != null) {
|
||||
stacks = new StackMapTableWriter(w, sm, output.getNewBytecodesToOldBytecodes());
|
||||
codeAttrCount++;
|
||||
} else { */
|
||||
|
||||
String[][] varTypes = null;
|
||||
int[] newToOld = output.getNewBytecodesToOldBytecodes();
|
||||
int[][] vars = LocalVariableTableReader.makeVarMap(oldCode);
|
||||
|
@ -445,9 +442,9 @@ final public class ClassInstrumenter {
|
|||
}
|
||||
}
|
||||
}
|
||||
stacks = new StackMapTableWriter(w, md, output, cha, varTypes);
|
||||
codeAttrCount++;
|
||||
// }
|
||||
|
||||
stacks = new StackMapTableWriter(w, md, output, cha, varTypes, sm);
|
||||
codeAttrCount++;
|
||||
} catch (IOException | FailureException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -14,6 +14,8 @@ public class StackMapConstants {
|
|||
void write(OutputStream s, ClassWriter writer) throws IOException;
|
||||
|
||||
int size();
|
||||
|
||||
boolean isObject();
|
||||
}
|
||||
|
||||
public enum Item implements StackMapType {
|
||||
|
@ -53,6 +55,7 @@ public class StackMapConstants {
|
|||
this.code = (byte)code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObject() {
|
||||
return false;
|
||||
}
|
||||
|
@ -89,6 +92,11 @@ public class StackMapConstants {
|
|||
return Item.ITEM_Uninitalized.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "uninit:" + type;
|
||||
|
@ -111,6 +119,11 @@ public class StackMapConstants {
|
|||
return Item.ITEM_Object.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "obj:" + type;
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.ibm.wala.shrikeCT.StackMapConstants.Item;
|
|||
import com.ibm.wala.shrikeCT.StackMapConstants.ObjectType;
|
||||
import com.ibm.wala.shrikeCT.StackMapConstants.StackMapFrame;
|
||||
import com.ibm.wala.shrikeCT.StackMapConstants.StackMapType;
|
||||
import com.ibm.wala.shrikeCT.StackMapConstants.UninitializedType;
|
||||
|
||||
public class StackMapTableReader extends AttributeReader {
|
||||
private List<StackMapFrame> frames;
|
||||
|
@ -18,7 +19,9 @@ public class StackMapTableReader extends AttributeReader {
|
|||
|
||||
private StackMapType item(int offset) throws InvalidClassFileException {
|
||||
Item item = StackMapConstants.items[cr.getByte(offset)];
|
||||
if (item.isObject()) {
|
||||
if (Item.ITEM_Uninitalized == item) {
|
||||
return new UninitializedType("#" + cr.getUShort(offset+1) + "#unknown");
|
||||
} else if (Item.ITEM_Object == item) {
|
||||
return new ObjectType(cr.getCP().getCPClass(cr.getUShort(offset+1)));
|
||||
} else {
|
||||
return item;
|
||||
|
@ -32,7 +35,7 @@ public class StackMapTableReader extends AttributeReader {
|
|||
int ptr = attr + 8;
|
||||
for(int i = 0; i < entries; i++) {
|
||||
int frameType = (0x000000ff & cr.getByte(ptr++));
|
||||
if (frameType < 63) {
|
||||
if (frameType < 64) {
|
||||
int offset = frameType;
|
||||
frames.add(new StackMapFrame(frameType, offset, new StackMapType[0], new StackMapType[0]));
|
||||
} else if (frameType < 128) {
|
||||
|
@ -73,7 +76,7 @@ public class StackMapTableReader extends AttributeReader {
|
|||
StackMapType[] stack = new StackMapType[ numStack ];
|
||||
for(int j = 0; j < numStack; j++) {
|
||||
stack[j] = item(ptr);
|
||||
ptr += (stack[j] instanceof ObjectType)? 3: 1;
|
||||
ptr += (stack[j].isObject())? 3: 1;
|
||||
}
|
||||
|
||||
frames.add(new StackMapFrame(frameType, offset, locals, stack));
|
||||
|
|
|
@ -52,9 +52,13 @@ public class StackMapTableWriter extends Element {
|
|||
}
|
||||
|
||||
public StackMapTableWriter(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha, String[][] vars) throws FailureException, IOException {
|
||||
this(writer, stackMapTable(writer, method, output, cha, vars));
|
||||
this(writer, stackMapTable(writer, method, output, cha, vars, null));
|
||||
}
|
||||
|
||||
|
||||
public StackMapTableWriter(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha, String[][] vars, List<StackMapFrame> reuseFrames) throws FailureException, IOException {
|
||||
this(writer, stackMapTable(writer, method, output, cha, vars, reuseFrames));
|
||||
}
|
||||
|
||||
private static List<StackMapFrame> remapStackFrames(List<StackMapFrame> sm, int[] newBytecodesToOldBytecodes) {
|
||||
// mapping to new bytecode
|
||||
Map<Integer,Integer> oldToNew = HashMapFactory.make();
|
||||
|
@ -189,7 +193,9 @@ public class StackMapTableWriter extends Element {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static List<StackMapFrame> stackMapTable(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha, String[][] vars) throws FailureException, IOException {
|
||||
public static List<StackMapFrame> stackMapTable(ClassWriter writer, MethodData method, Output output, ClassHierarchyProvider cha, String[][] vars, List<StackMapFrame> reuseFrames) throws FailureException, IOException {
|
||||
int idx = 0;
|
||||
|
||||
List<StackMapFrame> frames = new ArrayList<StackMapFrame>();
|
||||
|
||||
int[] instructionToBytecode = output.getInstructionOffsets();
|
||||
|
@ -199,7 +205,7 @@ public class StackMapTableWriter extends Element {
|
|||
if (cha != null) {
|
||||
typeChecker.setClassHierarchy(cha);
|
||||
}
|
||||
typeChecker.verifyCollectAll();
|
||||
typeChecker.computeTypes();
|
||||
BitSet bbs = typeChecker.getBasicBlockStarts();
|
||||
|
||||
int offset = 0;
|
||||
|
@ -210,9 +216,6 @@ public class StackMapTableWriter extends Element {
|
|||
if (isUselessGoto(insts[i], i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// full frame
|
||||
byte frameType = (byte)255;
|
||||
|
||||
// offset delta
|
||||
int position = instructionToBytecode[i];
|
||||
|
@ -220,6 +223,18 @@ public class StackMapTableWriter extends Element {
|
|||
int frameOffset = offset==0? position: position - offset - 1;
|
||||
offset = position;
|
||||
|
||||
if (reuseFrames != null) {
|
||||
if (reuseFrames.get(idx).getOffset() == frameOffset) {
|
||||
frames.add(reuseFrames.get(idx++));
|
||||
continue;
|
||||
} else {
|
||||
reuseFrames = null;
|
||||
}
|
||||
}
|
||||
|
||||
// full frame
|
||||
byte frameType = (byte)255;
|
||||
|
||||
// locals
|
||||
String[] localTypes = typeChecker.getLocalTypes()[i];
|
||||
StackMapType[] localWriteTypes;
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -44,9 +44,9 @@
|
|||
<module>com.ibm.wala.ide-feature</module>
|
||||
<module>com.ibm.wala.ide</module>
|
||||
<module>com.ibm.wala.ide.tests</module>
|
||||
<module>com.ibm.wala.ide.jdt</module>
|
||||
<module>com.ibm.wala.ide.jsdt</module>
|
||||
<module>com.ibm.wala.ide.jsdt.tests</module>
|
||||
<module>com.ibm.wala.ide.jdt</module>
|
||||
<module>com.ibm.wala.ide.jdt.test</module>
|
||||
|
||||
<module>com.ibm.wala.dalvik</module>
|
||||
|
@ -71,7 +71,7 @@
|
|||
<target>
|
||||
<artifact>
|
||||
<groupId>com.ibm.wala.target</groupId>
|
||||
<artifactId>e44</artifactId>
|
||||
<artifactId>e42</artifactId>
|
||||
<version>${project-version}</version>
|
||||
</artifact>
|
||||
</target>
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
|
||||
<unit id="org.eclipse.emf.sdk.feature.group" version="2.8.3.v20130125-0826"/>
|
||||
<unit id="org.eclipse.wst.web_ui.feature.feature.group" version="3.4.2.v201211061806-7O7MFu3EMkBK01NbrfU9ATE5cdZFz-OoeYjaI4d2"/>
|
||||
<unit id="org.eclipse.wst.jsdt.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.wst.jsdt.ui" version="0.0.0"/>
|
||||
<unit id="org.eclipse.sdk.ide" version="4.2.2.M20130204-1200"/>
|
||||
<unit id="org.eclipse.jdt.source.feature.group" version="3.8.2.v20130116-090414-8-8nFu3FNOfwKLRuqgXKIy9z0I83"/>
|
||||
<unit id="org.eclipse.jdt.feature.group" version="3.8.2.v20130116-090414-8-8nFu3FNOfwKLRuqgXKIy9z0I83"/>
|
||||
<unit id="org.eclipse.osgi" version="0.0.0"/>
|
||||
<repository location="http://download.eclipse.org/releases/juno"/>
|
||||
</location>
|
||||
</locations>
|
||||
|
|
|
@ -2,10 +2,28 @@
|
|||
<?pde version="3.8"?><target name="WALA Eclipse Luna Target Platform" sequenceNumber="130">
|
||||
<locations>
|
||||
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="slicer" includeSource="true" type="InstallableUnit">
|
||||
<unit id="org.eclipse.platform.ide" version="0.0.0"/>
|
||||
<unit id="org.eclipse.jdt.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.pde.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.e4.rcp.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.ecf.core.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.ecf.core.ssl.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.ecf.filetransfer.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.ecf.filetransfer.httpclient4.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.ecf.filetransfer.httpclient4.ssl.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.ecf.filetransfer.ssl.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.emf.common.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.emf.ecore.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.emf.sdk.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.equinox.p2.core.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.equinox.p2.extras.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.equinox.p2.rcp.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.equinox.p2.user.ui.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.help.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.jdt.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.jdt.source.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.pde.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.platform.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.rcp.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.sdk.ide" version="0.0.0"/>
|
||||
<unit id="org.eclipse.wst.jsdt.feature.feature.group" version="0.0.0"/>
|
||||
<unit id="org.eclipse.wst.web_ui.feature.feature.group" version="0.0.0"/>
|
||||
<repository location="http://download.eclipse.org/releases/luna"/>
|
||||
</location>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<artifactId>targets</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>e42</module>
|
||||
<module>e44</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
Loading…
Reference in New Issue