Merge branch 'wala' into master
Conflicts: com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/loader/JavaSourceLoaderImpl.java com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaInstructionFactory.java com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaInvokeInstruction.java com.ibm.wala.cast.js.test/harness-src/com/ibm/wala/cast/js/test/TestSimpleCallGraphShape.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/html/WebPageLoaderFactory.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/loader/JavaScriptLoader.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ssa/JSInstructionFactory.java com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ssa/JavaScriptInvoke.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/AstCallGraph.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/ssa/AbstractLexicalInvoke.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/ssa/AstInstructionFactory.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/ssa/AstLexicalRead.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/ssa/AstLexicalWrite.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/ssa/FixedParametersInvokeInstruction.java com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java com.ibm.wala.core/.classpath com.ibm.wala.core/.settings/org.eclipse.jdt.core.prefs com.ibm.wala.ide/src/com/ibm/wala/ide/util/ProgressMonitorDelegate.java com.ibm.wala.util/src/com/ibm/wala/util/NullProgressMonitor.java com.ibm.wala.util/src/com/ibm/wala/util/ProgressMaster.java
This commit is contained in:
commit
428a3975ed
|
@ -1,3 +1,6 @@
|
|||
language: java
|
||||
before_install:
|
||||
- "export DISPLAY=:99.0"
|
||||
- "sh -e /etc/init.d/xvfb start"
|
||||
install: mvn clean verify -DskipTests=true -B -q
|
||||
script: mvn clean verify -B -q
|
||||
|
|
|
@ -5,14 +5,6 @@
|
|||
version="1.3.4.qualifier"
|
||||
provider-name="%providerName">
|
||||
|
||||
<copyright url="%copyrightURL">
|
||||
%copyright
|
||||
</copyright>
|
||||
|
||||
<license url="%licenseURL">
|
||||
%license
|
||||
</license>
|
||||
|
||||
<plugin
|
||||
id="com.ibm.wala.core"
|
||||
download-size="0"
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
<feature id="com.ibm.wala-feature">
|
||||
<category name="main"/>
|
||||
</feature>
|
||||
<feature id="com.ibm.wala-feature.source">
|
||||
<category name="main"/>
|
||||
</feature>
|
||||
<feature id="com.ibm.wala.ide-feature">
|
||||
<category name="main"/>
|
||||
</feature>
|
||||
|
|
|
@ -22,9 +22,9 @@ import com.ibm.wala.classLoader.ClassLoaderFactoryImpl;
|
|||
import com.ibm.wala.classLoader.ClassLoaderImpl;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.config.SetOfClasses;
|
||||
|
||||
public class PolyglotClassLoaderFactory extends ClassLoaderFactoryImpl {
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
package com.ibm.wala.cast.java.translator.polyglot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
@ -869,7 +870,7 @@ public class PolyglotJava2CAstTranslator {
|
|||
handleThrowsFromCall(ctorInst, n, wc);
|
||||
|
||||
return makeNode(wc, fFactory, n, CAstNode.LOCAL_SCOPE, makeNode(wc, fFactory, n, CAstNode.BLOCK_EXPR, makeNode(wc, fFactory,
|
||||
n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(tmpName, true)), newNode), callNode, makeNode(wc,
|
||||
n, CAstNode.DECL_STMT, fFactory.makeConstant(new InternalCAstSymbol(tmpName, getTypeDict().getCAstTypeFor(n.type()), true)), newNode), callNode, makeNode(wc,
|
||||
fFactory, n, CAstNode.VAR, fFactory.makeConstant(tmpName))));
|
||||
}
|
||||
|
||||
|
@ -1280,7 +1281,7 @@ public class PolyglotJava2CAstTranslator {
|
|||
public CAstNode visit(Synchronized s, WalkContext wc) {
|
||||
CAstNode exprNode = walkNodes(s.expr(), wc);
|
||||
String exprName = fFactory.makeUnique();
|
||||
CAstNode declStmt = makeNode(wc, fFactory, s, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(exprName, true)),
|
||||
CAstNode declStmt = makeNode(wc, fFactory, s, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(exprName, getTypeDict().getCAstTypeFor(s.expr().type()), true)),
|
||||
exprNode);
|
||||
CAstNode monitorEnterNode = makeNode(wc, fFactory, s, CAstNode.MONITOR_ENTER, makeNode(wc, fFactory, s, CAstNode.VAR,
|
||||
fFactory.makeConstant(exprName)));
|
||||
|
@ -1362,7 +1363,7 @@ public class PolyglotJava2CAstTranslator {
|
|||
|
||||
boolean isFinal = ld.flags().flags().isFinal();
|
||||
|
||||
return makeNode(wc, fFactory, ld, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(ld.name().id().toString(), isFinal,
|
||||
return makeNode(wc, fFactory, ld, CAstNode.DECL_STMT, fFactory.makeConstant(new CAstSymbolImpl(ld.name().id().toString(), getTypeDict().getCAstTypeFor(type), isFinal,
|
||||
defaultValue)), initNode);
|
||||
}
|
||||
|
||||
|
@ -2515,8 +2516,8 @@ public class PolyglotJava2CAstTranslator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return getURL().openConnection().getInputStream();
|
||||
public Reader getReader() throws IOException {
|
||||
return new InputStreamReader(getURL().openConnection().getInputStream());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ package com.ibm.wala.cast.java.translator.polyglot;
|
|||
|
||||
import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine;
|
||||
import com.ibm.wala.classLoader.ClassLoaderFactory;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.util.config.SetOfClasses;
|
||||
|
||||
public class PolyglotJavaSourceAnalysisEngine extends JavaSourceAnalysisEngine {
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ import com.ibm.wala.cast.java.ipa.callgraph.JavaSourceAnalysisScope;
|
|||
import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl;
|
||||
import com.ibm.wala.cast.java.translator.SourceModuleTranslator;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.config.SetOfClasses;
|
||||
|
||||
public class PolyglotSourceLoaderImpl extends JavaSourceLoaderImpl {
|
||||
protected final IRTranslatorExtension fExtInfo;
|
||||
|
|
|
@ -351,10 +351,10 @@ public abstract class IRTests {
|
|||
CallGraph callGraph;
|
||||
try {
|
||||
callGraph = engine.buildDefaultCallGraph();
|
||||
System.err.println(callGraph.toString());
|
||||
//System.err.println(callGraph.toString());
|
||||
|
||||
// If we've gotten this far, IR has been produced.
|
||||
dumpIR(callGraph, sources, assertReachable);
|
||||
//dumpIR(callGraph, sources, assertReachable);
|
||||
|
||||
// Now check any assertions as to source mapping
|
||||
for (IRAssertion IRAssertion : ca) {
|
||||
|
|
|
@ -604,7 +604,7 @@ public abstract class JavaIRTests extends IRTests {
|
|||
Set<CGNode> roots = cg.getNodes(sliceRootRef);
|
||||
Pair<Collection<Statement>, SDG> y = AstJavaSlicer.computeAssertionSlice(cg, pa, roots, false);
|
||||
Collection<Statement> slice = y.fst;
|
||||
SlicerTest.dumpSlice(slice);
|
||||
//SlicerTest.dumpSlice(slice);
|
||||
Assert.assertEquals(0, SlicerTest.countAllocations(slice));
|
||||
Assert.assertEquals(1, SlicerTest.countPutfields(slice));
|
||||
|
||||
|
@ -613,7 +613,7 @@ public abstract class JavaIRTests extends IRTests {
|
|||
roots = cg.getNodes(sliceRootRef);
|
||||
y = AstJavaSlicer.computeAssertionSlice(cg, pa, roots, false);
|
||||
slice = y.fst;
|
||||
SlicerTest.dumpSlice(slice);
|
||||
// SlicerTest.dumpSlice(slice);
|
||||
Assert.assertEquals(2, SlicerTest.countAllocations(slice));
|
||||
Assert.assertEquals(2, SlicerTest.countPutfields(slice));
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
package com.ibm.wala.cast.java.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
||||
|
@ -25,7 +27,6 @@ import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
|||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
|
@ -35,6 +36,8 @@ import com.ibm.wala.ssa.SymbolTable;
|
|||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.config.FileOfClasses;
|
||||
import com.ibm.wala.util.config.SetOfClasses;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -105,7 +108,8 @@ public abstract class JavaSourceAnalysisEngine extends AbstractAnalysisEngine {
|
|||
scope = makeSourceAnalysisScope();
|
||||
|
||||
if (getExclusionsFile() != null) {
|
||||
scope.setExclusions(FileOfClasses.createFileOfClasses(new File(getExclusionsFile())));
|
||||
InputStream is = new File(getExclusionsFile()).exists()? new FileInputStream(getExclusionsFile()): FileProvider.class.getClassLoader().getResourceAsStream(getExclusionsFile());
|
||||
scope.setExclusions(new FileOfClasses(is));
|
||||
}
|
||||
|
||||
for (Module M : this.systemEntries) {
|
||||
|
|
|
@ -12,11 +12,13 @@ package com.ibm.wala.cast.java.examples.ast;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.cast.java.types.JavaPrimitiveTypeMap;
|
||||
import com.ibm.wala.cast.tree.CAst;
|
||||
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||
import com.ibm.wala.cast.tree.CAstEntity;
|
||||
import com.ibm.wala.cast.tree.CAstNode;
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap;
|
||||
import com.ibm.wala.cast.tree.CAstType;
|
||||
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
||||
import com.ibm.wala.cast.tree.rewrite.CAstRewriter;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
|
@ -219,7 +221,7 @@ public class SynchronizedBlockDuplicator extends
|
|||
|
||||
// the conditional test
|
||||
CAstNode test = Ast.makeNode(CAstNode.CALL, Ast.makeNode(CAstNode.VOID), Ast.makeConstant(f),
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName)));
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(varName), Ast.makeConstant(JavaPrimitiveTypeMap.lookupType("boolean"))));
|
||||
|
||||
// the new if conditional
|
||||
return Ast.makeNode(CAstNode.IF_STMT, test, copyNodes(n, cfg, new SyncContext(true, n, c), nodeMap),
|
||||
|
|
|
@ -115,7 +115,7 @@ public class AstJavaSlicer extends Slicer {
|
|||
Collection<CGNode> partialRoots, boolean multiThreadedCode) throws IllegalArgumentException, CancelException {
|
||||
CallGraph pcg = PartialCallGraph.make(CG, new LinkedHashSet<CGNode>(partialRoots));
|
||||
SDG sdg = new SDG(pcg, pa, new AstJavaModRef(), DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
|
||||
System.err.println(("SDG:\n" + sdg));
|
||||
//System.err.println(("SDG:\n" + sdg));
|
||||
Set<Statement> stmts = gatherAssertions(CG, partialRoots);
|
||||
if (multiThreadedCode) {
|
||||
// Grab anything that has "side effects" under JMM
|
||||
|
|
|
@ -61,10 +61,9 @@ import com.ibm.wala.classLoader.Language;
|
|||
import com.ibm.wala.classLoader.Module;
|
||||
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;
|
||||
|
@ -78,6 +77,7 @@ import com.ibm.wala.types.TypeReference;
|
|||
import com.ibm.wala.types.annotations.Annotation;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.config.SetOfClasses;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
|
@ -574,19 +574,9 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AstJavaInvokeInstruction JavaInvokeInstruction(int iindex, int result, int[] params, int exception, CallSiteReference site) {
|
||||
return new AstJavaInvokeInstruction(iindex, result, params, exception, site);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AstJavaInvokeInstruction JavaInvokeInstruction(int iindex, int[] params, int exception, CallSiteReference site) {
|
||||
return new AstJavaInvokeInstruction(iindex, params, exception, site);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AstJavaInvokeInstruction JavaInvokeInstruction(int iindex, int[] results, int[] params, int exception, CallSiteReference site,
|
||||
Access[] lexicalReads, Access[] lexicalWrites) {
|
||||
return new AstJavaInvokeInstruction(iindex, results, params, exception, site, lexicalReads, lexicalWrites);
|
||||
public AstJavaInvokeInstruction JavaInvokeInstruction(final int iindex, int result[], int[] params, int exception, CallSiteReference site) {
|
||||
return result == null ? new AstJavaInvokeInstruction(iindex, params, exception, site) : new AstJavaInvokeInstruction(iindex, result[0],
|
||||
params, exception, site);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -655,8 +645,8 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AstLexicalRead LexicalRead(int iindex, int lhs, String definer, String globalName) {
|
||||
return new AstLexicalRead(iindex, lhs, definer, globalName);
|
||||
public AstLexicalRead LexicalRead(int iindex, int lhs, String definer, String globalName, TypeReference type) {
|
||||
return new AstLexicalRead(iindex, lhs, definer, globalName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -670,8 +660,8 @@ public abstract class JavaSourceLoaderImpl extends ClassLoaderImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AstLexicalWrite LexicalWrite(int iindex, String definer, String globalName, int rhs) {
|
||||
return new AstLexicalWrite(iindex, definer, globalName, rhs);
|
||||
public AstLexicalWrite LexicalWrite(int iindex, String definer, String globalName, TypeReference type, int rhs) {
|
||||
return new AstLexicalWrite(iindex, definer, globalName, type, rhs);
|
||||
}
|
||||
|
||||
public SSAThrowInstruction NonExceptingThrowInstruction(int iindex, int exception) {
|
||||
|
|
|
@ -11,20 +11,15 @@
|
|||
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 iindex, int result, int[] params, int exception, CallSiteReference site);
|
||||
AstJavaInvokeInstruction JavaInvokeInstruction(int iindex, int result[], int[] params, int exception, CallSiteReference site);
|
||||
|
||||
AstJavaInvokeInstruction JavaInvokeInstruction(int iindex, int[] params, int exception, CallSiteReference site);
|
||||
|
||||
AstJavaInvokeInstruction JavaInvokeInstruction(int iindex, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites);
|
||||
|
||||
EnclosingObjectReference EnclosingObjectReference(int iidnex, int lval, TypeReference type);
|
||||
EnclosingObjectReference EnclosingObjectReference(int iindex, int lval, TypeReference type);
|
||||
|
||||
AstJavaNewEnclosingInstruction JavaNewEnclosingInstruction(int iindex, int result, NewSiteReference site, int enclosing);
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@ 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.cast.ir.ssa.FixedParametersInvokeInstruction;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.JavaLanguage;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
|
@ -21,14 +20,7 @@ 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 {
|
||||
public class AstJavaInvokeInstruction extends FixedParametersInvokeInstruction {
|
||||
|
||||
protected AstJavaInvokeInstruction(int iindex, int results[], int[] params, int exception, CallSiteReference site) {
|
||||
super(iindex, results, params, exception, site);
|
||||
|
@ -46,34 +38,24 @@ public class AstJavaInvokeInstruction extends FixedParametersLexicalInvokeInstru
|
|||
this(iindex, null, params, exception, site);
|
||||
}
|
||||
|
||||
public AstJavaInvokeInstruction(int iindex, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads,
|
||||
Access[] lexicalWrites) {
|
||||
super(iindex, 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(iindex, results, params, exception, getCallSite(), lexicalReads,
|
||||
lexicalWrites);
|
||||
protected SSAInstruction copyInstruction(SSAInstructionFactory insts, int results[], int[] params, int exception) {
|
||||
return ((AstJavaInstructionFactory) insts).JavaInvokeInstruction(iindex, 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package com.ibm.wala.cast.java.translator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -207,7 +208,7 @@ public class JavaCAst2IRTranslator extends AstTranslator {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doGlobalWrite(WalkContext context, String name, int rval) {
|
||||
protected void doGlobalWrite(WalkContext context, String name, TypeReference type, int rval) {
|
||||
Assertions.UNREACHABLE("doGlobalWrite() called for Java code???");
|
||||
}
|
||||
|
||||
|
@ -410,6 +411,40 @@ public class JavaCAst2IRTranslator extends AstTranslator {
|
|||
}
|
||||
}
|
||||
|
||||
private CAstType getType(final String name) {
|
||||
return new CAstType.Class() {
|
||||
|
||||
@Override
|
||||
public Collection getSupertypes() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CAstQualifier> getQualifiers() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
protected CAstType topType() {
|
||||
return getType("java.lang.Object");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CAstType exceptionType() {
|
||||
return getType("java.lang.Exception");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="com.ibm.wala.cast.java.polyglot" default="getJars" basedir=".">
|
||||
<project name="com.ibm.wala.cast.js.html.nu_validator" default="getJars" basedir=".">
|
||||
|
||||
<property name="basews" value="${ws}"/>
|
||||
<property name="baseos" value="${os}"/>
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.cast.js.html.nu_validator;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
@ -41,7 +42,7 @@ import com.ibm.wala.util.collections.Pair;
|
|||
public class NuValidatorHtmlParser implements IHtmlParser {
|
||||
|
||||
@Override
|
||||
public void parse(final URL url, final InputStream reader, final IHtmlCallback handler, final String fileName) {
|
||||
public void parse(final URL url, final Reader reader, final IHtmlCallback handler, final String fileName) {
|
||||
URL xx = null;
|
||||
try {
|
||||
xx = new URL("file://" + fileName);
|
||||
|
|
|
@ -11,9 +11,10 @@ Require-Bundle: com.ibm.wala.cast.js.rhino;bundle-version="1.0.0",
|
|||
com.ibm.wala.cast.js.test;bundle-version="1.0.0",
|
||||
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
||||
com.ibm.wala.core.tests;bundle-version="1.1.3",
|
||||
org.junit4;bundle-version="4.3.1",
|
||||
com.ibm.wala.cast.js.test.data;bundle-version="1.3.4"
|
||||
com.ibm.wala.cast.js.test.data;bundle-version="1.3.4",
|
||||
org.junit;bundle-version="4.0.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.js.rhino.test,
|
||||
Export-Package: com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test,
|
||||
com.ibm.wala.cast.js.rhino.test,
|
||||
com.ibm.wala.cast.js.test
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
|
||||
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
|
||||
import com.ibm.wala.cast.js.test.TestJSCallGraphShape;
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
import com.ibm.wala.cast.js.util.CallGraph2JSON;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.NullProgressMonitor;
|
||||
import com.ibm.wala.util.ProgressMaster;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
|
||||
public abstract class AbstractFieldBasedTest extends TestJSCallGraphShape {
|
||||
|
||||
protected CGUtil util;
|
||||
|
||||
public AbstractFieldBasedTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
util = new CGUtil(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
protected JSCallGraph runTest(String script, Object[][] assertions, BuilderType... builderTypes) throws IOException, WalaException, Error, CancelException {
|
||||
return runTest(TestFieldBasedCG.class.getClassLoader().getResource(script), assertions, builderTypes);
|
||||
}
|
||||
|
||||
protected JSCallGraph runTest(URL url, Object[][] assertions, BuilderType... builderTypes) throws IOException, WalaException, Error, CancelException {
|
||||
JSCallGraph cg = null;
|
||||
for(BuilderType builderType : builderTypes) {
|
||||
ProgressMaster monitor = ProgressMaster.make(new NullProgressMonitor(), 30000, true);
|
||||
try {
|
||||
cg = util.buildCG(url, builderType, monitor);
|
||||
verifyGraphAssertions(cg, assertions);
|
||||
} catch(AssertionFailedError afe) {
|
||||
throw new AssertionFailedError(builderType + ": " + afe.getMessage());
|
||||
}
|
||||
}
|
||||
return cg;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void dumpCG(JSCallGraph cg) {
|
||||
CallGraph2JSON.IGNORE_HARNESS = false;
|
||||
Map<String, Set<String>> edges = CallGraph2JSON.extractEdges(cg);
|
||||
for(String callsite : edges.keySet())
|
||||
for(String callee : edges.get(callsite))
|
||||
System.out.println(callsite + " -> " + callee);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,11 +26,11 @@ import com.ibm.wala.cast.js.callgraph.fieldbased.PessimisticCallGraphBuilder;
|
|||
import com.ibm.wala.cast.js.callgraph.fieldbased.WorklistBasedOptimisticCallgraphBuilder;
|
||||
import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
||||
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
|
||||
import com.ibm.wala.cast.js.html.WebUtil;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
||||
import com.ibm.wala.cast.js.test.JSCallGraphBuilderUtil;
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.cast.js.util.CallGraph2JSON;
|
||||
|
@ -42,6 +42,7 @@ import com.ibm.wala.ipa.callgraph.Entrypoint;
|
|||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.NullProgressMonitor;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
|
||||
|
@ -60,10 +61,22 @@ public class CGUtil {
|
|||
this.translatorFactory = translatorFactory;
|
||||
}
|
||||
|
||||
public JSCallGraph buildCG(URL url, BuilderType builderType) throws IOException, WalaException, Error {
|
||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||
SourceModule[] scripts = extractScript(url).toArray(new SourceModule[]{});
|
||||
JavaScriptLoaderFactory loaders = makeLoaderFactory(url);
|
||||
public JSCallGraph buildCG(URL url, BuilderType builderType) throws IOException, WalaException, CancelException {
|
||||
return buildCG(url, builderType, new NullProgressMonitor());
|
||||
}
|
||||
|
||||
public JSCallGraph buildCG(URL url, BuilderType builderType, IProgressMonitor monitor) throws IOException, WalaException, CancelException {
|
||||
JavaScriptLoaderFactory loaders = makeLoaderFactory(url);
|
||||
SourceModule[] scripts;
|
||||
if (url.getFile().endsWith(".js")) {
|
||||
scripts = new SourceModule[]{
|
||||
new SourceURLModule(url),
|
||||
JSCallGraphBuilderUtil.getPrologueFile("prologue.js")
|
||||
};
|
||||
} else {
|
||||
scripts = JSCallGraphBuilderUtil.makeHtmlScope(url, loaders);
|
||||
}
|
||||
|
||||
CAstAnalysisScope scope = new CAstAnalysisScope(scripts, loaders, Collections.singleton(JavaScriptLoader.JS));
|
||||
IClassHierarchy cha = ClassHierarchy.make(scope, loaders, JavaScriptLoader.JS);
|
||||
Util.checkForFrontEndErrors(cha);
|
||||
|
@ -83,26 +96,14 @@ public class CGUtil {
|
|||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
return builder.buildCallGraph(new NullProgressMonitor());
|
||||
} catch (CancelException e) {
|
||||
return null;
|
||||
}
|
||||
return builder.buildCallGraph(roots, monitor).fst;
|
||||
}
|
||||
|
||||
private JavaScriptLoaderFactory makeLoaderFactory(URL url) {
|
||||
return url.getFile().endsWith(".js") ? new JavaScriptLoaderFactory(translatorFactory) : new WebPageLoaderFactory(translatorFactory);
|
||||
}
|
||||
|
||||
private Set<? extends SourceModule> extractScript(URL url) throws Error {
|
||||
if(url.getFile().endsWith(".js")) {
|
||||
return Collections.singleton(new SourceURLModule(url));
|
||||
} else {
|
||||
return WebUtil.extractScriptFromHTML(url).fst;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, WalaException, Error {
|
||||
public static void main(String[] args) throws IOException, WalaException, Error, CancelException {
|
||||
JSSourceExtractor.DELETE_UPON_EXIT = true;
|
||||
URL url = new File(args[0]).toURI().toURL();
|
||||
System.err.println("Analysing " + url);
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
|
||||
public class FieldBasedCGGamesTest extends AbstractFieldBasedTest {
|
||||
|
||||
@Test
|
||||
public void testBunnyHunt() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.themaninblue.com/experiment/BunnyHunt/"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBomberman() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.e-forum.ro/bomberman/dynagame.html"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBeslimed() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.markus-inger.de/test/game.php"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiggAttack() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.pixastic.com/labs/digg_attack/"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRiverRaider() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://playstar.mobi/games/riverraider/index.html?playerId=&gameId=8&highscore=102425"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSolitaire() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.inmensia.com/files/solitaire1.0.html"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test(expected = CancelException.class)
|
||||
public void testWorldOfSolitaire() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://worldofsolitaire.com/"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinesweeper() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.inmensia.com/files/minesweeper1.0.html"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProtoRPG() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.protorpg.com/games/protorpg/?game=prologue"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBattleship() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest(new URL("http://www.sinkmyship.com/battleship/single.html"), new Object[][]{}, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -11,53 +11,16 @@
|
|||
package com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
|
||||
import com.ibm.wala.cast.js.rhino.callgraph.fieldbased.test.CGUtil.BuilderType;
|
||||
import com.ibm.wala.cast.js.test.TestJSCallGraphShape;
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
import com.ibm.wala.cast.js.util.CallGraph2JSON;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
|
||||
public class TestFieldBasedCG extends TestJSCallGraphShape {
|
||||
protected CGUtil util;
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
util = new CGUtil(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
private void runTest(String script, Object[][] assertions, BuilderType... builderTypes) throws IOException, WalaException, Error {
|
||||
for(BuilderType builderType : builderTypes) {
|
||||
URL url = TestFieldBasedCG.class.getClassLoader().getResource(script);
|
||||
JSCallGraph cg = util.buildCG(url, builderType);
|
||||
try {
|
||||
verifyGraphAssertions(cg, assertions);
|
||||
} catch(AssertionFailedError afe) {
|
||||
throw new AssertionFailedError(builderType + ": " + afe.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void dumpCG(JSCallGraph cg) {
|
||||
CallGraph2JSON.IGNORE_HARNESS = false;
|
||||
Map<String, Set<String>> edges = CallGraph2JSON.extractEdges(cg);
|
||||
for(String callsite : edges.keySet())
|
||||
for(String callee : edges.get(callsite))
|
||||
System.out.println(callsite + " -> " + callee);
|
||||
}
|
||||
|
||||
public class TestFieldBasedCG extends AbstractFieldBasedTest {
|
||||
private static final Object[][] assertionsForSimpleJS = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "suffix:simple.js" } },
|
||||
new Object[] { "suffix:simple.js", new String[] { "suffix:foo", "suffix:bar", "suffix:A", "suffix:Function" } },
|
||||
|
@ -66,7 +29,7 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testSimpleJS() throws IOException, WalaException, Error {
|
||||
public void testSimpleJS() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/simple.js", assertionsForSimpleJS, BuilderType.PESSIMISTIC, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
|
@ -77,7 +40,7 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testOneshot() throws IOException, WalaException, Error {
|
||||
public void testOneshot() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/oneshot.js", assertionsForOneShot, BuilderType.PESSIMISTIC, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
|
@ -89,7 +52,7 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testCallbacks() throws IOException, WalaException, Error {
|
||||
public void testCallbacks() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/callbacks.js", assertionsForCallbacks, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
|
@ -98,7 +61,7 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testLexical() throws IOException, WalaException, Error {
|
||||
public void testLexical() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/lexical.js", assertionsForLexical, BuilderType.PESSIMISTIC, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
|
@ -108,7 +71,7 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testReflectiveCall() throws IOException, WalaException, Error {
|
||||
public void testReflectiveCall() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/reflective_calls.js", assertionsForReflectiveCall, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
|
@ -118,7 +81,7 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testNew() throws IOException, WalaException, Error {
|
||||
public void testNew() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/new.js", assertionsForNew, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
|
@ -128,7 +91,13 @@ public class TestFieldBasedCG extends TestJSCallGraphShape {
|
|||
};
|
||||
|
||||
@Test
|
||||
public void testCallbacks2() throws IOException, WalaException, Error {
|
||||
public void testCallbacks2() throws IOException, WalaException, Error, CancelException {
|
||||
runTest("tests/fieldbased/callbacks2.js", assertionsForCallbacks2, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST);
|
||||
}
|
||||
|
||||
// @Test
|
||||
public void testBug2979() throws IOException, WalaException, Error, CancelException {
|
||||
System.err.println(runTest("pages/2979.html", new Object[][]{}, BuilderType.PESSIMISTIC, BuilderType.OPTIMISTIC, BuilderType.OPTIMISTIC_WORKLIST));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,9 +92,8 @@ public class HTMLCGBuilder {
|
|||
// the code below belongs somewhere else!!!
|
||||
// the bound of 4 is what is needed to pass our current framework tests
|
||||
builder.setContextSelector(new RecursionCheckContextSelector(builder.getContextSelector()));
|
||||
ProgressMaster master = ProgressMaster.make(new NullProgressMonitor());
|
||||
ProgressMaster master = ProgressMaster.make(new NullProgressMonitor(), timeout * 1000, false);
|
||||
if (timeout > 0) {
|
||||
master.setMillisPerWorkItem(timeout * 1000);
|
||||
master.beginTask("runSolver", 1);
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
|
|
|
@ -95,7 +95,7 @@ public class PrintIRs {
|
|||
// add model for DOM APIs
|
||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||
URL url = (new File(filename)).toURI().toURL();
|
||||
Pair<Set<MappedSourceModule>, File> p = WebUtil.extractScriptFromHTML(url);
|
||||
Pair<Set<MappedSourceModule>, File> p = WebUtil.extractScriptFromHTML(url, true);
|
||||
SourceModule[] scripts = p.fst.toArray(new SourceModule[] {});
|
||||
JavaScriptLoaderFactory loaders = new WebPageLoaderFactory(JSCallGraphUtil.getTranslatorFactory());
|
||||
CAstAnalysisScope scope = new CAstAnalysisScope(scripts, loaders, Collections.singleton(JavaScriptLoader.JS));
|
||||
|
|
|
@ -41,7 +41,6 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
|
|||
b.makeCallGraph(b.getOptions());
|
||||
PointerAnalysis PA = b.getPointerAnalysis();
|
||||
// just make sure this does not crash
|
||||
computeIkIdToVns(PA);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -74,7 +73,12 @@ public class TestSimpleCallGraphShapeRhino extends TestSimpleCallGraphShape {
|
|||
public void testNonLoopBreakLabel() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "non_loop_break.js");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testForInName() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "for_in_name.js");
|
||||
}
|
||||
|
||||
@Test(expected = WalaException.class)
|
||||
public void testParseError() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "portal-example-simple.html");
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
|
||||
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
|
||||
<mapEntry key="[debug]" value="org.eclipse.jdt.junit.launchconfig"/>
|
||||
<mapEntry key="[run]" value="org.eclipse.jdt.junit.launchconfig"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.debug.ui.ATTR_CAPTURE_IN_FILE" value="/tmp/console.txt"/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="com.ibm.wala.cast.java.polyglot" default="getJars" basedir=".">
|
||||
<project name="com.ibm.wala.cast.js.rhino" default="getJars" basedir=".">
|
||||
|
||||
<property name="basews" value="${ws}"/>
|
||||
<property name="baseos" value="${os}"/>
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Collections;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mozilla.javascript.CompilerEnvirons;
|
||||
import org.mozilla.javascript.ErrorReporter;
|
||||
|
@ -108,6 +109,7 @@ import com.ibm.wala.cast.tree.impl.CAstSymbolImpl;
|
|||
import com.ibm.wala.classLoader.SourceModule;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
|
||||
|
@ -294,7 +296,7 @@ public class RhinoToAstTranslator {
|
|||
}
|
||||
|
||||
private CAstNode handleNew(WalkContext context, String globalName, CAstNode arguments[]) {
|
||||
return handleNew(context, readName(context, globalName), arguments);
|
||||
return handleNew(context, readName(context, null, globalName), arguments);
|
||||
}
|
||||
|
||||
private CAstNode handleNew(WalkContext context, CAstNode value, CAstNode arguments[]) {
|
||||
|
@ -497,8 +499,7 @@ public class RhinoToAstTranslator {
|
|||
|
||||
@Override
|
||||
public CAstType getType() {
|
||||
Assertions.UNREACHABLE("JuliansUnnamedCAstEntity$2.getType()");
|
||||
return null;
|
||||
return JSAstTranslator.Any;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,9 +558,13 @@ public class RhinoToAstTranslator {
|
|||
return n;
|
||||
}
|
||||
|
||||
private CAstNode readName(WalkContext context, String name) {
|
||||
private CAstNode readName(WalkContext context, AstNode node, String name) {
|
||||
CAstNode cn = makeVarRef(name);
|
||||
context.cfg().map(cn, cn);
|
||||
if (node != null) {
|
||||
context.cfg().map(node, cn);
|
||||
} else {
|
||||
context.cfg().map(cn, cn);
|
||||
}
|
||||
CAstNode target = context.getCatchTarget();
|
||||
if (target != null) {
|
||||
context.cfg().add(cn, target, JavaScriptTypes.ReferenceError);
|
||||
|
@ -729,14 +734,16 @@ public class RhinoToAstTranslator {
|
|||
public CAstNode visitContinueStatement(ContinueStatement node,
|
||||
WalkContext arg) {
|
||||
CAstNode continueStmt;
|
||||
Node target;
|
||||
if (node.getLabel() != null) {
|
||||
continueStmt = Ast.makeNode(CAstNode.GOTO, Ast.makeConstant(node.getLabel().getIdentifier()));
|
||||
target = arg.getContinueFor(node.getLabel().getIdentifier());
|
||||
} else {
|
||||
continueStmt = Ast.makeNode(CAstNode.GOTO);
|
||||
target = arg.getContinueFor(null);
|
||||
}
|
||||
|
||||
arg.cfg().map(node, continueStmt);
|
||||
|
||||
Node target = node.getTarget();
|
||||
arg.cfg().add(node, target, null);
|
||||
|
||||
return continueStmt;
|
||||
|
@ -805,15 +812,15 @@ public class RhinoToAstTranslator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) {
|
||||
String tempName = "for in loop temp";
|
||||
|
||||
public CAstNode visitForInLoop(ForInLoop node, WalkContext arg) {
|
||||
// set up
|
||||
AstNode object = node.getIteratedObject();
|
||||
CAstNode loopTemp =
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName)),
|
||||
visit(object, arg));
|
||||
|
||||
CAstNode object = visit(node.getIteratedObject(), arg);
|
||||
String tempName = "for in loop temp";
|
||||
CAstNode[] loopHeader = new CAstNode[]{
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(tempName, JSAstTranslator.Any))),
|
||||
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName)), object)
|
||||
};
|
||||
|
||||
CAstNode initNode;
|
||||
AstNode var = node.getIterator();
|
||||
assert var instanceof Name || var instanceof VariableDeclaration || var instanceof LetNode : var.getClass() + " " + var;
|
||||
|
@ -838,13 +845,13 @@ public class RhinoToAstTranslator {
|
|||
if (isLet) {
|
||||
initNode =
|
||||
Ast.makeNode(CAstNode.DECL_STMT,
|
||||
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
|
||||
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
|
||||
Ast.makeNode(CAstNode.EACH_ELEMENT_GET, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName))));
|
||||
|
||||
} else {
|
||||
arg.addNameDecl(
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
|
||||
readName(arg, "$$undefined")));
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
|
||||
readName(arg, null, "$$undefined")));
|
||||
|
||||
initNode =
|
||||
Ast.makeNode(CAstNode.ASSIGN,
|
||||
|
@ -858,15 +865,21 @@ public class RhinoToAstTranslator {
|
|||
CAstNode breakLabel = visit(breakStmt, arg);
|
||||
AstNode contStmt = makeEmptyLabelStmt("contLabel");
|
||||
CAstNode contLabel = visit(contStmt, arg);
|
||||
// TODO: Figure out why this is needed to make the correlation extraction tests pass
|
||||
// TODO: remove this silly label
|
||||
AstNode garbageStmt = makeEmptyLabelStmt("garbageLabel");
|
||||
CAstNode garbageLabel = visit(garbageStmt, arg);
|
||||
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
|
||||
CAstNode body = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
initNode,
|
||||
visit(node.getBody(), loopContext),
|
||||
contLabel);
|
||||
garbageLabel);
|
||||
|
||||
CAstNode loop = Ast.makeNode(CAstNode.LOCAL_SCOPE,
|
||||
Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
loopTemp,
|
||||
loopHeader[0],
|
||||
loopHeader[1],
|
||||
contLabel,
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
Ast.makeNode(CAstNode.EACH_ELEMENT_HAS_NEXT,
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant(tempName))),
|
||||
|
@ -885,9 +898,10 @@ public class RhinoToAstTranslator {
|
|||
|
||||
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
|
||||
|
||||
CAstNode loop = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
CAstNode loop;
|
||||
CAstNode top = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
visit(node.getInitializer(), arg),
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
loop = Ast.makeNode(CAstNode.LOOP,
|
||||
visit(node.getCondition(), arg),
|
||||
Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
visit(node.getBody(), loopContext),
|
||||
|
@ -895,7 +909,7 @@ public class RhinoToAstTranslator {
|
|||
visit(node.getIncrement(), arg))),
|
||||
breakLabel);
|
||||
arg.cfg().map(node, loop);
|
||||
return loop;
|
||||
return top;
|
||||
}
|
||||
|
||||
private CAstNode[] gatherCallArguments(Node call, WalkContext context) {
|
||||
|
@ -912,7 +926,7 @@ public class RhinoToAstTranslator {
|
|||
public CAstNode visitFunctionCall(FunctionCall n, WalkContext context) {
|
||||
if (!isPrimitiveCall(context, n)) {
|
||||
AstNode callee = n.getTarget();
|
||||
int thisBaseVarNum = ++baseVarNum;
|
||||
int thisBaseVarNum = ++tempVarNum;
|
||||
WalkContext child = new MemberDestructuringContext(context, callee, thisBaseVarNum);
|
||||
CAstNode fun = visit(callee, child);
|
||||
|
||||
|
@ -924,10 +938,10 @@ public class RhinoToAstTranslator {
|
|||
Ast.makeNode(CAstNode.LOCAL_SCOPE,
|
||||
Ast.makeNode(CAstNode.BLOCK_EXPR,
|
||||
Ast.makeNode(CAstNode.DECL_STMT,
|
||||
Ast.makeConstant(new CAstSymbolImpl(operationReceiverName(thisBaseVarNum))),
|
||||
Ast.makeConstant(new CAstSymbolImpl(operationReceiverName(thisBaseVarNum), JSAstTranslator.Any)),
|
||||
Ast.makeConstant(null)),
|
||||
Ast.makeNode(CAstNode.DECL_STMT,
|
||||
Ast.makeConstant(new CAstSymbolImpl(operationElementName(thisBaseVarNum))),
|
||||
Ast.makeConstant(new CAstSymbolImpl(operationElementName(thisBaseVarNum), JSAstTranslator.Any)),
|
||||
Ast.makeConstant(null)),
|
||||
fun,
|
||||
makeCall(operationElementVar(thisBaseVarNum), operationReceiverVar(thisBaseVarNum), args, context, "dispatch")));
|
||||
|
@ -995,7 +1009,7 @@ public class RhinoToAstTranslator {
|
|||
CAstNode r = visit(node.getRight(), arg);
|
||||
return Ast.makeNode(CAstNode.LOCAL_SCOPE,
|
||||
Ast.makeNode(CAstNode.BLOCK_EXPR,
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("or temp")), l),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("or temp", JSAstTranslator.Any)), l),
|
||||
Ast.makeNode(CAstNode.IF_EXPR,
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant("or temp")),
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant("or temp")),
|
||||
|
@ -1005,7 +1019,7 @@ public class RhinoToAstTranslator {
|
|||
CAstNode r = visit(node.getRight(), arg);
|
||||
return Ast.makeNode(CAstNode.LOCAL_SCOPE,
|
||||
Ast.makeNode(CAstNode.BLOCK_EXPR,
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("and temp")), l),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl("and temp", JSAstTranslator.Any)), l),
|
||||
Ast.makeNode(CAstNode.IF_EXPR,
|
||||
Ast.makeNode(CAstNode.VAR, Ast.makeConstant("and temp")),
|
||||
r,
|
||||
|
@ -1059,6 +1073,9 @@ public class RhinoToAstTranslator {
|
|||
case Token.NULL: {
|
||||
return Ast.makeConstant(null);
|
||||
}
|
||||
case Token.DEBUGGER: {
|
||||
return Ast.makeConstant(null);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("unexpected keyword literal " + node + " (" + node.getType() +")");
|
||||
}
|
||||
|
@ -1098,7 +1115,7 @@ public class RhinoToAstTranslator {
|
|||
for(VariableInitializer init : decl.getVariables()) {
|
||||
stmts[i++] =
|
||||
Ast.makeNode(CAstNode.DECL_STMT,
|
||||
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
|
||||
Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
|
||||
visit(init, arg));
|
||||
}
|
||||
stmts[i++] = visit(node.getBody(), arg);
|
||||
|
@ -1107,7 +1124,7 @@ public class RhinoToAstTranslator {
|
|||
|
||||
@Override
|
||||
public CAstNode visitName(Name n, WalkContext context) {
|
||||
return readName(context, n.getString());
|
||||
return readName(context, n, n.getString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1344,8 +1361,8 @@ public class RhinoToAstTranslator {
|
|||
arg.addNameDecl(
|
||||
noteSourcePosition(
|
||||
arg,
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString())),
|
||||
readName(arg, "$$undefined")),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(init.getTarget().getString(), JSAstTranslator.Any)),
|
||||
readName(arg, null, "$$undefined")),
|
||||
node));
|
||||
|
||||
if (init.getInitializer() == null) {
|
||||
|
@ -1380,11 +1397,10 @@ public class RhinoToAstTranslator {
|
|||
WalkContext loopContext = makeLoopContext(node, arg, breakStmt, contStmt);
|
||||
|
||||
CAstNode loop = Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
contLabel,
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
visit(node.getCondition(), arg),
|
||||
Ast.makeNode(CAstNode.BLOCK_STMT,
|
||||
visit(node.getBody(), loopContext),
|
||||
contLabel)),
|
||||
visit(node.getBody(), loopContext)),
|
||||
breakLabel);
|
||||
|
||||
arg.cfg().map(node, loop);
|
||||
|
@ -2277,16 +2293,16 @@ private CAstNode[] walkChildren(final Node n, WalkContext context) {
|
|||
*/
|
||||
public CAstEntity translateToCAst() throws Error, IOException, com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error {
|
||||
class CAstErrorReporter implements ErrorReporter {
|
||||
private Warning w = null;
|
||||
private Set<Warning> w = HashSetFactory.make();
|
||||
|
||||
@Override
|
||||
public void error(final String arg0, final String arg1, final int arg2, final String arg3, int arg4) {
|
||||
w = new Warning(Warning.SEVERE) {
|
||||
w.add(new Warning(Warning.SEVERE) {
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return arg0 + ": " + arg1 + "@" + arg2 + ": " + arg3;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2315,7 +2331,7 @@ private CAstNode[] walkChildren(final Node n, WalkContext context) {
|
|||
|
||||
AstRoot top = P.parse(sourceReader, scriptName, 1);
|
||||
|
||||
if (reporter.w != null) {
|
||||
if (! reporter.w.isEmpty()) {
|
||||
throw new TranslatorToCAst.Error(reporter.w);
|
||||
}
|
||||
|
||||
|
@ -2337,7 +2353,7 @@ private CAstNode[] walkChildren(final Node n, WalkContext context) {
|
|||
|
||||
final private Reader sourceReader;
|
||||
|
||||
private int baseVarNum = 0;
|
||||
private int tempVarNum = 0;
|
||||
|
||||
private final DoLoopTranslator doLoopTranslator;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="com.ibm.wala.cast.java.polyglot" default="getJars" basedir=".">
|
||||
<project name="com.ibm.wala.cast.js.test.data" default="getJars" basedir=".">
|
||||
|
||||
<property name="basews" value="${ws}"/>
|
||||
<property name="baseos" value="${os}"/>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<HTML>
|
||||
|
||||
<TITLE>Welcome!</TITLE>
|
||||
|
||||
Hi
|
||||
|
||||
<SCRIPT>
|
||||
|
||||
function onload_handler() {}
|
||||
|
||||
window.onload = onload_handler;
|
||||
</SCRIPT>
|
||||
|
||||
<BR>
|
||||
Welcome to our system
|
||||
|
||||
</HTML>
|
|
@ -0,0 +1,10 @@
|
|||
var f = function for_in_with_assign(b) {
|
||||
var a,d,n,e;
|
||||
n=1;
|
||||
for(e=arguments.length;n<e;n+=1)
|
||||
for(a in d=arguments[n],d)
|
||||
Object.prototype.hasOwnProperty.call(d,a)&&(b[a]=d[a]);
|
||||
return b;
|
||||
}
|
||||
|
||||
f(new Object());
|
|
@ -0,0 +1,74 @@
|
|||
var f = function(arrangedSSIDs,accessPointSpecs,exactLocation)
|
||||
{
|
||||
for (var i=0; i < accessPointSpecs.length; i++)
|
||||
{
|
||||
var definedSSID = accessPointSpecs[i].SSID;
|
||||
var definedMAC = accessPointSpecs[i].MAC;
|
||||
|
||||
if (arrangedSSIDs[definedSSID])
|
||||
{
|
||||
if (definedMAC)
|
||||
{
|
||||
if (arrangedSSIDs[definedSSID][definedMAC])
|
||||
{
|
||||
arrangedSSIDs[definedSSID][definedMAC].checked = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
arrangedSSIDs[definedSSID].checked = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (exactLocation)
|
||||
{
|
||||
for (var key in arrangedSSIDs)
|
||||
{
|
||||
var SSID = arrangedSSIDs[key];
|
||||
if (!SSID.checked)
|
||||
{
|
||||
var checkedMACs = false;
|
||||
for (var MAC in SSID)
|
||||
{
|
||||
checkedMACs = true;
|
||||
var obj = SSID[MAC];
|
||||
if (!obj.checked) return false;
|
||||
}
|
||||
|
||||
if (!checkedMACs) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
var g = function(transactionId) {
|
||||
var obj,http,i;
|
||||
try
|
||||
{
|
||||
http = new XMLHttpRequest();
|
||||
obj = { conn:http, tId:transactionId, xhr: true };
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
for(i=0; i<this._msxml_progid.length; ++i){
|
||||
try
|
||||
{
|
||||
http = new ActiveXObject(this._msxml_progid[i]);
|
||||
obj = { conn:http, tId:transactionId, xhr: true };
|
||||
break;
|
||||
}
|
||||
catch(e1){}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
f();
|
||||
g();
|
File diff suppressed because one or more lines are too long
|
@ -4,16 +4,15 @@ Bundle-Name: WALA JavaScript Test Plug-in
|
|||
Bundle-SymbolicName: com.ibm.wala.cast.js.test;singleton:=true
|
||||
Bundle-Version: 1.3.4.qualifier
|
||||
Bundle-ClassPath: test.jar
|
||||
Bundle-Activator: com.ibm.wala.cast.js.test.JavaScriptTestPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Require-Bundle: com.ibm.wala.cast.js,
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.core,
|
||||
org.eclipse.core.runtime,
|
||||
com.ibm.wala.core.tests,
|
||||
org.junit4;bundle-version="4.3.1",
|
||||
com.ibm.wala.cast.test;bundle-version="1.0.0",
|
||||
com.ibm.wala.cast.js.test.data;bundle-version="1.3.4"
|
||||
com.ibm.wala.cast.js.test.data;bundle-version="1.3.4",
|
||||
org.junit;bundle-version="4.0.0"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.js.test
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
|
|
|
@ -11,16 +11,16 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
import com.ibm.wala.cast.js.html.MappedSourceModule;
|
||||
import com.ibm.wala.cast.js.html.WebPageLoaderFactory;
|
||||
import com.ibm.wala.cast.js.html.WebUtil;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSAnalysisOptions;
|
||||
|
@ -34,7 +34,6 @@ import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
|||
import com.ibm.wala.cast.loader.CAstAbstractLoader;
|
||||
import com.ibm.wala.cast.tree.rewrite.CAstRewriterFactory;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.classLoader.SourceModule;
|
||||
import com.ibm.wala.classLoader.SourceURLModule;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
|
@ -48,6 +47,8 @@ import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|||
import com.ibm.wala.ssa.IRFactory;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
|
||||
/**
|
||||
* TODO this class is a mess. rewrite.
|
||||
|
@ -97,28 +98,39 @@ public class JSCallGraphBuilderUtil extends com.ibm.wala.cast.js.ipa.callgraph.J
|
|||
return makeCG(loaders, scope, builderType, AstIRFactory.makeDefaultFactory());
|
||||
}
|
||||
|
||||
public static URL getURLforFile(String dir, String name) {
|
||||
URL script = JSCallGraphBuilderUtil.class.getClassLoader().getResource(dir + File.separator + name);
|
||||
if (script == null) {
|
||||
script = JSCallGraphBuilderUtil.class.getClassLoader().getResource(dir + "/" + name);
|
||||
public static URL getURLforFile(String dir, String name) throws IOException {
|
||||
File f = null;
|
||||
FileProvider provider = new FileProvider();
|
||||
try {
|
||||
f = provider.getFile(dir + File.separator + name, JSCallGraphBuilderUtil.class.getClassLoader());
|
||||
} catch (FileNotFoundException e) {
|
||||
// I guess we need to do this on Windows sometimes? --MS
|
||||
// if this fails, we won't catch the exception
|
||||
f = provider.getFile(dir + "/" + name, JSCallGraphBuilderUtil.class.getClassLoader());
|
||||
}
|
||||
assert script != null : "cannot find " + dir + " and " + name;
|
||||
return script;
|
||||
return f.toURI().toURL();
|
||||
}
|
||||
|
||||
static AnalysisScope makeScriptScope(String dir, String name, JavaScriptLoaderFactory loaders) throws IOException {
|
||||
return makeScriptScope(getURLforFile(dir, name), dir, name, loaders);
|
||||
}
|
||||
|
||||
public static SourceModule getPrologueFile(final String name) {
|
||||
return new SourceURLModule(JSCallGraphBuilderUtil.class.getClassLoader().getResource(name)) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static AnalysisScope makeScriptScope(URL script, String dir, String name, JavaScriptLoaderFactory loaders) throws IOException {
|
||||
AnalysisScope scope;
|
||||
if (script.openConnection() instanceof JarURLConnection) {
|
||||
scope = makeScope(new URL[] { script }, loaders, JavaScriptLoader.JS);
|
||||
} else {
|
||||
scope = makeScope(new SourceFileModule[] { makeSourceModule(script, dir, name) }, loaders, JavaScriptLoader.JS);
|
||||
}
|
||||
|
||||
return scope;
|
||||
return makeScope(
|
||||
new SourceModule[] {
|
||||
(script.openConnection() instanceof JarURLConnection)? new SourceURLModule(script): makeSourceModule(script, dir, name),
|
||||
getPrologueFile("prologue.js")
|
||||
}, loaders, JavaScriptLoader.JS);
|
||||
|
||||
}
|
||||
|
||||
public static JSCFABuilder makeScriptCGBuilder(String dir, String name) throws IOException, WalaException {
|
||||
|
@ -151,26 +163,37 @@ public class JSCallGraphBuilderUtil extends com.ibm.wala.cast.js.ipa.callgraph.J
|
|||
}
|
||||
|
||||
public static JSCFABuilder makeHTMLCGBuilder(URL url, CGBuilderType builderType) throws IOException, WalaException {
|
||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||
SourceModule[] scripts;
|
||||
IRFactory<IMethod> irFactory = AstIRFactory.makeDefaultFactory();
|
||||
CAstRewriterFactory preprocessor = builderType.extractCorrelatedPairs ? new CorrelatedPairExtractorFactory(translatorFactory, url) : null;
|
||||
JavaScriptLoaderFactory loaders = new WebPageLoaderFactory(translatorFactory, preprocessor);
|
||||
try {
|
||||
Set<MappedSourceModule> script = WebUtil.extractScriptFromHTML(url).fst;
|
||||
scripts = script.toArray(new SourceModule[script.size()]);
|
||||
} catch (Error e) {
|
||||
SourceModule dummy = new SourceURLModule(url);
|
||||
scripts = new SourceModule[]{ dummy };
|
||||
((CAstAbstractLoader)loaders.getTheLoader()).addMessage(dummy, e.warning);
|
||||
}
|
||||
JSCFABuilder builder = makeCGBuilder(loaders, scripts, builderType, irFactory);
|
||||
SourceModule[] scriptsArray = makeHtmlScope(url, loaders);
|
||||
|
||||
JSCFABuilder builder = makeCGBuilder(loaders, scriptsArray, builderType, irFactory);
|
||||
if(builderType.extractCorrelatedPairs)
|
||||
builder.setContextSelector(new PropertyNameContextSelector(builder.getAnalysisCache(), 2, builder.getContextSelector()));
|
||||
builder.setBaseURL(url);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static SourceModule[] makeHtmlScope(URL url, JavaScriptLoaderFactory loaders) {
|
||||
Set<SourceModule> scripts = HashSetFactory.make();
|
||||
|
||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||
scripts.add(getPrologueFile("prologue.js"));
|
||||
scripts.add(getPrologueFile("preamble.js"));
|
||||
|
||||
try {
|
||||
scripts.addAll(WebUtil.extractScriptFromHTML(url, true).fst);
|
||||
} catch (Error e) {
|
||||
SourceModule dummy = new SourceURLModule(url);
|
||||
scripts.add(dummy);
|
||||
((CAstAbstractLoader)loaders.getTheLoader()).addMessage(dummy, e.warning);
|
||||
}
|
||||
|
||||
SourceModule[] scriptsArray = scripts.toArray(new SourceModule[ scripts.size() ]);
|
||||
return scriptsArray;
|
||||
}
|
||||
|
||||
public static CallGraph makeHTMLCG(URL url) throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
PropagationCallGraphBuilder b = makeHTMLCGBuilder(url);
|
||||
CallGraph CG = b.makeCallGraph(b.getOptions());
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
|||
import com.ibm.wala.cast.js.ipa.callgraph.ArgumentSpecialization;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSAnalysisOptions;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSZeroOrOneXCFABuilder;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
|
@ -41,15 +42,15 @@ public abstract class TestArgumentSensitivity extends TestJSCallGraphShape {
|
|||
new Object[] { "tests/args.js/a", new String[] { "tests/args.js/y", "tests/args.js/z", "!tests/args.js/wrong" } } };
|
||||
|
||||
@Test public void testArgs() throws IOException, IllegalArgumentException, CancelException, ClassHierarchyException, WalaException {
|
||||
JavaScriptLoaderFactory loaders = JSCallGraphBuilderUtil.makeLoaders(null);
|
||||
JavaScriptLoaderFactory loaders = JSCallGraphUtil.makeLoaders(null);
|
||||
AnalysisScope scope = JSCallGraphBuilderUtil.makeScriptScope("tests", "args.js", loaders);
|
||||
|
||||
IClassHierarchy cha = JSCallGraphBuilderUtil.makeHierarchy(scope, loaders);
|
||||
IClassHierarchy cha = JSCallGraphUtil.makeHierarchy(scope, loaders);
|
||||
com.ibm.wala.cast.js.util.Util.checkForFrontEndErrors(cha);
|
||||
Iterable<Entrypoint> roots = JSCallGraphBuilderUtil.makeScriptRoots(cha);
|
||||
JSAnalysisOptions options = JSCallGraphBuilderUtil.makeOptions(scope, cha, roots);
|
||||
Iterable<Entrypoint> roots = JSCallGraphUtil.makeScriptRoots(cha);
|
||||
JSAnalysisOptions options = JSCallGraphUtil.makeOptions(scope, cha, roots);
|
||||
|
||||
AnalysisCache cache = JSCallGraphBuilderUtil.makeCache(new ArgumentSpecialization.ArgumentCountIRFactory(options.getSSAOptions()));
|
||||
AnalysisCache cache = CAstCallGraphUtil.makeCache(new ArgumentSpecialization.ArgumentCountIRFactory(options.getSSAOptions()));
|
||||
|
||||
JSCFABuilder builder = new JSZeroOrOneXCFABuilder(cha, options, cache, null, null, ZeroXInstanceKeys.ALLOCATIONS, false);
|
||||
builder.setContextSelector(new ArgumentSpecialization.ArgumentCountContextSelector(builder.getContextSelector()));
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.io.IOException;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ComparisonFailure;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -50,20 +51,27 @@ public abstract class TestForInBodyExtraction {
|
|||
|
||||
public void testRewriter(String testName, String in, String out) {
|
||||
File tmp = null;
|
||||
String expected = null;
|
||||
String actual = null;
|
||||
try {
|
||||
tmp = File.createTempFile("test", ".js");
|
||||
FileUtil.writeFile(tmp, in);
|
||||
CAstImpl ast = new CAstImpl();
|
||||
String actual = new CAstDumper().dump(new ClosureExtractor(ast, ForInBodyExtractionPolicy.FACTORY).rewrite(parseJS(tmp, ast)));
|
||||
actual = new CAstDumper().dump(new ClosureExtractor(ast, ForInBodyExtractionPolicy.FACTORY).rewrite(parseJS(tmp, ast)));
|
||||
actual = eraseGeneratedNames(actual);
|
||||
|
||||
FileUtil.writeFile(tmp, out);
|
||||
String expected = new CAstDumper().dump(parseJS(tmp, ast));
|
||||
expected = new CAstDumper().dump(parseJS(tmp, ast));
|
||||
expected = eraseGeneratedNames(expected);
|
||||
|
||||
Assert.assertEquals(testName, expected, actual);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ComparisonFailure e) {
|
||||
System.err.println("Comparison Failure in " + testName + "!");
|
||||
System.err.println(expected);
|
||||
System.err.println(actual);
|
||||
throw e;
|
||||
} finally {
|
||||
if(tmp != null && tmp.exists())
|
||||
tmp.delete();
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.junit.Before;
|
|||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
||||
import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.PropertyNameContextSelector;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
|
@ -37,7 +38,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
URL url = getClass().getClassLoader().getResource("pages/page3.html");
|
||||
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
@Test public void testPage3WithHack() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
|
@ -45,7 +46,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||
addHackedForInLoopSensitivity(builder);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
@Ignore("This test now blows up due to proper handling of the || construct, used in extend(). Should handle this eventually.")
|
||||
|
@ -54,7 +55,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||
addHackedForInLoopSensitivity(builder);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -87,7 +88,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
@Test public void testBadForInWithoutHack() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForBadForin);
|
||||
}
|
||||
|
||||
|
@ -106,7 +107,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin.js");
|
||||
addHackedForInLoopSensitivity(B);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForBadForin);
|
||||
verifyGraphAssertions(CG, assertionsForBadForinHackPrecision);
|
||||
}
|
||||
|
@ -131,7 +132,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
@Test public void testbadforin2WithoutHack() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin2.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForbadforin2);
|
||||
}
|
||||
|
||||
|
@ -150,7 +151,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin2.js");
|
||||
addHackedForInLoopSensitivity(B);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForbadforin2);
|
||||
verifyGraphAssertions(CG, assertionsForbadforin2HackPrecision);
|
||||
}
|
||||
|
@ -159,7 +160,7 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "badforin3.js");
|
||||
addHackedForInLoopSensitivity(B);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,14 +12,16 @@ package com.ibm.wala.cast.js.test;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||
import com.ibm.wala.cast.test.TestCallGraphShape;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
|
||||
public abstract class TestJSCallGraphShape extends TestCallGraphShape {
|
||||
|
||||
@Override
|
||||
protected Collection getNodes(CallGraph CG, String functionIdentifier) {
|
||||
return JSCallGraphBuilderUtil.getNodes(CG, functionIdentifier);
|
||||
protected Collection<CGNode> getNodes(CallGraph CG, String functionIdentifier) {
|
||||
return JSCallGraphUtil.getNodes(CG, functionIdentifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,39 +11,25 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.PropertyNameContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException;
|
||||
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.callgraph.propagation.PropagationCallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.NullProgressMonitor;
|
||||
import com.ibm.wala.util.ProgressMaster;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.IVector;
|
||||
import com.ibm.wala.util.collections.Iterator2Collection;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.collections.SparseVector;
|
||||
import com.ibm.wala.util.intset.IntSetAction;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
||||
|
||||
|
@ -163,7 +149,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "forin.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForForin);
|
||||
}
|
||||
|
||||
|
@ -255,7 +241,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
B.getOptions().setTraceStringConstants(true);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForStringPrims);
|
||||
}
|
||||
|
||||
|
@ -466,7 +452,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "return_this.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForReturnThis);
|
||||
}
|
||||
|
||||
|
@ -561,7 +547,7 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
PropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "dispatch.js");
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
// JSCallGraphUtil.AVOID_DUMP = false;
|
||||
JSCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForDispatch);
|
||||
}
|
||||
|
||||
|
@ -671,7 +657,11 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
JSCallGraphBuilderUtil.makeScriptCG("tests", "dead_catch.js");
|
||||
}
|
||||
|
||||
@Ignore("need a bug fix")
|
||||
@Test
|
||||
public void testUglyLoopCrash() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "ssa-crash.js");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryFinallyCrash() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
JSCallGraphBuilderUtil.makeScriptCG("tests", "try-finally-crash.js");
|
||||
|
@ -682,26 +672,10 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
public void testManyStrings() throws IllegalArgumentException, IOException, CancelException, WalaException {
|
||||
SSAPropagationCallGraphBuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "many-strings.js");
|
||||
B.getOptions().setTraceStringConstants(true);
|
||||
final long startTime = System.currentTimeMillis();
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions(), new IProgressMonitor() {
|
||||
@Override
|
||||
public void beginTask(String task, int totalWork) {
|
||||
}
|
||||
@Override
|
||||
public boolean isCanceled() {
|
||||
return System.currentTimeMillis() > (startTime + 10000L);
|
||||
}
|
||||
@Override
|
||||
public void done() {
|
||||
}
|
||||
@Override
|
||||
public void worked(int units) {
|
||||
}
|
||||
public void subTask(String subTask) {
|
||||
}
|
||||
public void cancel() {
|
||||
}
|
||||
});
|
||||
ProgressMaster monitor = ProgressMaster.make(new NullProgressMonitor(), 10000, false);
|
||||
monitor.beginTask("build CG", 1);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions(), monitor);
|
||||
monitor.done();
|
||||
CAstCallGraphUtil.dumpCG(B.getPointerAnalysis(), CG);
|
||||
}
|
||||
|
||||
|
@ -713,51 +687,4 @@ public abstract class TestSimpleCallGraphShape extends TestJSCallGraphShape {
|
|||
// verifyGraphAssertions(CG, assertionsForDateProperty);
|
||||
}
|
||||
|
||||
protected IVector<Set<Pair<CGNode, Integer>>> computeIkIdToVns(PointerAnalysis pa) {
|
||||
|
||||
// Created by reversing the points to mapping for local pointer keys.
|
||||
// Instead of mapping (local) pointer keys to instance keys (with id), we
|
||||
// map instance keys to VnInContext (which carry the same information as
|
||||
// local pointer keys)
|
||||
|
||||
final IVector<Set<Pair<CGNode, Integer>>> ret = new SparseVector<Set<Pair<CGNode, Integer>>>();
|
||||
|
||||
for (PointerKey pk : pa.getPointerKeys()) {
|
||||
if (pk instanceof LocalPointerKey) {
|
||||
|
||||
final LocalPointerKey lpk = (LocalPointerKey) pk;
|
||||
// we filter out local pointer keys that have no uses.
|
||||
// NOTE: do to some weird behavior, we get pointer keys with vns that
|
||||
// don't exist, so we have to filter those before asking about uses.
|
||||
if (lpk.getNode().getDU().getDef(lpk.getValueNumber()) != null) {
|
||||
Iterator<SSAInstruction> uses = lpk.getNode().getDU().getUses(lpk.getValueNumber());
|
||||
if (uses.hasNext()) {
|
||||
OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
|
||||
if (pointsToSet == null || pointsToSet.getBackingSet() == null)
|
||||
continue;
|
||||
pointsToSet.getBackingSet().foreach(new IntSetAction() {
|
||||
@Override
|
||||
public void act(int ikId) {
|
||||
Set<Pair<CGNode, Integer>> s = ret.get(ikId);
|
||||
if (s == null) {
|
||||
s = HashSetFactory.make();
|
||||
ret.set(ikId, s);
|
||||
}
|
||||
s.add(Pair.make(lpk.getNode(), lpk.getValueNumber()));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
int i = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.net.URL;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.CAstCallGraphUtil;
|
||||
import com.ibm.wala.cast.js.html.IHtmlParser;
|
||||
import com.ibm.wala.cast.js.html.IHtmlParserFactory;
|
||||
import com.ibm.wala.cast.js.html.WebUtil;
|
||||
|
@ -269,7 +270,7 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
|||
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
// JSCallGraphBuilderUtil.AVOID_DUMP = false;
|
||||
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
verifySourceAssertions(CG, sourceAssertionsForList);
|
||||
}
|
||||
|
||||
|
@ -291,9 +292,23 @@ public abstract class TestSimplePageCallGraphShape extends TestJSCallGraphShape
|
|||
URL url = getClass().getClassLoader().getResource("pages/windowx.html");
|
||||
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
JSCallGraphBuilderUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForWindowx);
|
||||
}
|
||||
|
||||
private static final Object[][] assertionsForWindowOnload = new Object[][] {
|
||||
new Object[] { ROOT, new String[] { "windowonload.html" } },
|
||||
new Object[] { "windowonload.html", new String[] { "windowonload.html/__WINDOW_MAIN__" } },
|
||||
new Object[] { "windowonload.html/__WINDOW_MAIN__", new String[] { "windowonload.html/__WINDOW_MAIN__/onload_handler" } },
|
||||
};
|
||||
|
||||
@Test public void testWindowOnload() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
URL url = getClass().getClassLoader().getResource("pages/windowonload.html");
|
||||
JSCFABuilder builder = JSCallGraphBuilderUtil.makeHTMLCGBuilder(url);
|
||||
CallGraph CG = builder.makeCallGraph(builder.getOptions());
|
||||
CAstCallGraphUtil.dumpCG(builder.getPointerAnalysis(), CG);
|
||||
verifyGraphAssertions(CG, assertionsForWindowOnload);
|
||||
}
|
||||
|
||||
/*
|
||||
@Test public void testJQuery() throws IOException, IllegalArgumentException, CancelException, WalaException {
|
||||
|
|
|
@ -27,14 +27,14 @@ public class TestWebUtil extends WalaTestCase {
|
|||
@Test public void testAjaxslt() throws Error {
|
||||
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xslt.html");
|
||||
Assert.assertTrue(url != null);
|
||||
Set<MappedSourceModule> mod = WebUtil.extractScriptFromHTML( url ).fst;
|
||||
Set<MappedSourceModule> mod = WebUtil.extractScriptFromHTML( url, true ).fst;
|
||||
Assert.assertTrue(mod != null);
|
||||
}
|
||||
|
||||
@Test public void testAjaxpath() throws Error {
|
||||
URL url = getClass().getClassLoader().getResource("ajaxslt/test/xpath.html");
|
||||
Assert.assertTrue(url != null);
|
||||
Set<MappedSourceModule> mod = WebUtil.extractScriptFromHTML( url ).fst;
|
||||
Set<MappedSourceModule> mod = WebUtil.extractScriptFromHTML( url, true ).fst;
|
||||
Assert.assertTrue(mod != null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ Bundle-ClassPath: .,
|
|||
lib/jericho-html-3.2.jar
|
||||
Bundle-Activator: com.ibm.wala.cast.js.JavaScriptPlugin
|
||||
Bundle-Vendor: IBM
|
||||
Export-Package: com.ibm.wala.cast.js,
|
||||
Export-Package: .,
|
||||
com.ibm.wala.cast.js,
|
||||
com.ibm.wala.cast.js.analysis.typeInference,
|
||||
com.ibm.wala.cast.js.callgraph.fieldbased,
|
||||
com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="com.ibm.wala.cast.java.polyglot" default="getJars" basedir=".">
|
||||
<project name="com.ibm.wala.cast.js" default="getJars" basedir=".">
|
||||
|
||||
<property name="basews" value="${ws}"/>
|
||||
<property name="baseos" value="${os}"/>
|
||||
|
|
|
@ -80,11 +80,11 @@ Object.prototype = {
|
|||
|
||||
constructor: Object,
|
||||
|
||||
toString: function toString() {
|
||||
toString: function Object_prototype_toString() {
|
||||
return primitive("ObjectToString", this);
|
||||
},
|
||||
|
||||
toLocaleString: function toLocaleString() {
|
||||
toLocaleString: function Object_prototype_toLocaleString() {
|
||||
return primitive("ObjectToLocaleString", this);
|
||||
},
|
||||
|
||||
|
@ -196,6 +196,13 @@ local_array.prototype = {
|
|||
|
||||
push: function Array_prototype_push () {
|
||||
var n = this.length;
|
||||
|
||||
// nasty hack for field-sensitive builders
|
||||
// TODO: fix this somehow
|
||||
if (n == 0) {
|
||||
this[0] = arguments[0];
|
||||
}
|
||||
|
||||
for(var i = 0; i < arguments.length; i++) {
|
||||
this[ n++ ] = arguments[i];
|
||||
}
|
||||
|
|
|
@ -10,24 +10,20 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstContextInsensitiveSSAContextInterpreter;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraph;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.AbstractVertexVisitor;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraphBuilder;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.CallVertex;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
|
||||
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.js.ipa.callgraph.JSAnalysisOptions;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraph;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptConstructTargetSelector;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptEntryPoints;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JavaScriptFunctionDotCallTargetSelector;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.types.AstMethodReference;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
|
@ -41,16 +37,18 @@ import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
|
|||
import com.ibm.wala.ipa.callgraph.impl.AbstractRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ContextInsensitiveSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DefaultSSAInterpreter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DelegatingSSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.nCFAContextSelector;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.collections.Util;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
/**
|
||||
* Abstract call graph builder class for building a call graph from a field-based flow graph.
|
||||
|
@ -87,6 +85,11 @@ public abstract class FieldBasedCallGraphBuilder {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected FlowGraph flowGraphFactory() {
|
||||
FlowGraphBuilder builder = new FlowGraphBuilder(cha, cache);
|
||||
return builder.buildFlowGraph();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a flow graph for the program to be analysed.
|
||||
*/
|
||||
|
@ -95,12 +98,14 @@ public abstract class FieldBasedCallGraphBuilder {
|
|||
/**
|
||||
* Main entry point: builds a flow graph, then extracts a call graph and returns it.
|
||||
*/
|
||||
public JSCallGraph buildCallGraph(IProgressMonitor monitor) throws CancelException {
|
||||
public Pair<JSCallGraph,PointerAnalysis> buildCallGraph(Iterable<Entrypoint> eps, IProgressMonitor monitor) throws CancelException {
|
||||
long fgBegin, fgEnd, cgBegin, cgEnd;
|
||||
|
||||
if(LOG_TIMINGS) fgBegin = System.currentTimeMillis();
|
||||
|
||||
|
||||
MonitorUtil.beginTask(monitor, "flow graph", 1);
|
||||
FlowGraph flowGraph = buildFlowGraph(monitor);
|
||||
MonitorUtil.done(monitor);
|
||||
|
||||
if(LOG_TIMINGS) {
|
||||
fgEnd = System.currentTimeMillis();
|
||||
|
@ -108,29 +113,29 @@ public abstract class FieldBasedCallGraphBuilder {
|
|||
cgBegin = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
JSCallGraph cg = extract(flowGraph, monitor);
|
||||
MonitorUtil.beginTask(monitor, "extract call graph", 1);
|
||||
JSCallGraph cg = extract(flowGraph, eps, monitor);
|
||||
MonitorUtil.done(monitor);
|
||||
|
||||
if(LOG_TIMINGS) {
|
||||
cgEnd = System.currentTimeMillis();
|
||||
System.out.println("call graph extraction took " + (cgEnd-cgBegin)/1000.0 + " seconds");
|
||||
}
|
||||
|
||||
return cg;
|
||||
return Pair.make(cg,flowGraph.getPointerAnalysis(monitor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a call graph from a given flow graph.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected JSCallGraph extract(FlowGraph flowgraph, IProgressMonitor monitor) throws CancelException {
|
||||
// set up call graph
|
||||
protected JSCallGraph extract(FlowGraph flowgraph, Iterable<Entrypoint> eps, IProgressMonitor monitor) throws CancelException {
|
||||
// set up call graph
|
||||
final JSCallGraph cg = new JSCallGraph(cha, options, cache);
|
||||
cg.init();
|
||||
cg.setInterpreter(new DelegatingSSAContextInterpreter(new AstContextInsensitiveSSAContextInterpreter(options, cache), new DefaultSSAInterpreter(options, cache)));
|
||||
|
||||
|
||||
// set up call edges from fake root to all script nodes
|
||||
JavaScriptEntryPoints eps = new JavaScriptEntryPoints(cha, cha.getLoader(JavaScriptTypes.jsLoader));
|
||||
|
||||
// set up call edges from fake root to all script nodes
|
||||
AbstractRootMethod fakeRootMethod = (AbstractRootMethod)cg.getFakeRootNode().getMethod();
|
||||
CGNode fakeRootNode = cg.findOrCreateNode(fakeRootMethod, Everywhere.EVERYWHERE);
|
||||
for(Iterator<Entrypoint> iter = eps.iterator(); iter.hasNext();) {
|
||||
|
@ -145,65 +150,73 @@ public abstract class FieldBasedCallGraphBuilder {
|
|||
// now add genuine call edges
|
||||
Set<Pair<CallVertex, FuncVertex>> edges = extractCallGraphEdges(flowgraph, monitor);
|
||||
|
||||
for (Pair<CallVertex, FuncVertex> edge : edges) {
|
||||
CallVertex callVertex = edge.fst;
|
||||
FuncVertex targetVertex = edge.snd;
|
||||
IClass kaller = callVertex.getCaller().getConcreteType();
|
||||
CGNode caller = cg.findOrCreateNode(kaller.getMethod(AstMethodReference.fnSelector), Everywhere.EVERYWHERE);
|
||||
CallSiteReference site = callVertex.getSite();
|
||||
IMethod target = targetSelector.getCalleeTarget(caller, site, targetVertex.getConcreteType());
|
||||
if (caller.toString().contains("string_ctor"))
|
||||
System.err.println(caller + " " + site + " " + target);
|
||||
boolean isFunctionPrototypeCall = target != null
|
||||
&& target.getName().toString().startsWith(JavaScriptFunctionDotCallTargetSelector.SYNTHETIC_CALL_METHOD_PREFIX);
|
||||
if (isFunctionPrototypeCall) {
|
||||
handleFunctionPrototypeCallInvocation(flowgraph, monitor, cg, callVertex, caller, site, target);
|
||||
} else {
|
||||
addEdgeToJSCallGraph(cg, site, target, caller);
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<CallVertex, FuncVertex> edge : edges) {
|
||||
CallVertex callVertex = edge.fst;
|
||||
FuncVertex targetVertex = edge.snd;
|
||||
IClass kaller = callVertex.getCaller().getIClass();
|
||||
CGNode caller = cg.findOrCreateNode(kaller.getMethod(AstMethodReference.fnSelector), Everywhere.EVERYWHERE);
|
||||
CallSiteReference site = callVertex.getSite();
|
||||
IMethod target = targetSelector.getCalleeTarget(caller, site, targetVertex.getIClass());
|
||||
boolean isFunctionPrototypeCall = target != null
|
||||
&& target.getName().toString().startsWith(JavaScriptFunctionDotCallTargetSelector.SYNTHETIC_CALL_METHOD_PREFIX);
|
||||
if (isFunctionPrototypeCall) {
|
||||
handleFunctionPrototypeCallInvocation(flowgraph, monitor, cg, callVertex, caller, site, target);
|
||||
} else {
|
||||
addEdgeToJSCallGraph(cg, site, target, caller);
|
||||
}
|
||||
}
|
||||
|
||||
return cg;
|
||||
}
|
||||
|
||||
private void handleFunctionPrototypeCallInvocation(FlowGraph flowgraph, IProgressMonitor monitor, final JSCallGraph cg,
|
||||
private boolean handleFunctionPrototypeCallInvocation(FlowGraph flowgraph, IProgressMonitor monitor, final JSCallGraph cg,
|
||||
CallVertex callVertex, CGNode caller, CallSiteReference site,
|
||||
IMethod target) throws CancelException {
|
||||
// use to get 1-level of call string for Function.prototype.call, to
|
||||
// preserve the precision of the field-based call graph
|
||||
final nCFAContextSelector functionPrototypeCallSelector = new nCFAContextSelector(1, new ContextInsensitiveSelector());
|
||||
Context calleeContext = functionPrototypeCallSelector.getCalleeTarget(caller, site, target, null);
|
||||
addCGEdgeWithContext(cg, site, target, caller, calleeContext);
|
||||
boolean ret = addCGEdgeWithContext(cg, site, target, caller, calleeContext);
|
||||
CGNode functionPrototypeCallNode = cg.findOrCreateNode(target, calleeContext);
|
||||
// need to create nodes for reflective targets of call, and then add them
|
||||
// as callees of the synthetic method
|
||||
Collection<FuncVertex> reflectiveTargets = getReflectiveTargets(flowgraph, callVertex, monitor);
|
||||
OrdinalSet<FuncVertex> reflectiveTargets = getReflectiveTargets(flowgraph, callVertex, monitor);
|
||||
// there should only be one call site in the synthetic method
|
||||
CallSiteReference reflectiveCallSite = functionPrototypeCallNode.getIR().iterateCallSites().next();
|
||||
for (FuncVertex f : reflectiveTargets) {
|
||||
IMethod reflectiveTgtMethod = targetSelector.getCalleeTarget(functionPrototypeCallNode, reflectiveCallSite, f.getIClass());
|
||||
addEdgeToJSCallGraph(cg, reflectiveCallSite, reflectiveTgtMethod, functionPrototypeCallNode);
|
||||
IMethod reflectiveTgtMethod = targetSelector.getCalleeTarget(functionPrototypeCallNode, reflectiveCallSite, f.getConcreteType());
|
||||
ret |= addEdgeToJSCallGraph(cg, reflectiveCallSite, reflectiveTgtMethod, functionPrototypeCallNode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private IMethod addEdgeToJSCallGraph(final JSCallGraph cg, CallSiteReference site, IMethod target, CGNode caller)
|
||||
private boolean addEdgeToJSCallGraph(final JSCallGraph cg, CallSiteReference site, IMethod target, CGNode caller)
|
||||
throws CancelException {
|
||||
return addCGEdgeWithContext(cg, site, target, caller, Everywhere.EVERYWHERE);
|
||||
}
|
||||
|
||||
Set<IClass> constructedTypes = HashSetFactory.make();
|
||||
|
||||
Everywhere targetContext = Everywhere.EVERYWHERE;
|
||||
@SuppressWarnings("deprecation")
|
||||
private IMethod addCGEdgeWithContext(final JSCallGraph cg, CallSiteReference site, IMethod target, CGNode caller,
|
||||
private boolean addCGEdgeWithContext(final JSCallGraph cg, CallSiteReference site, IMethod target, CGNode caller,
|
||||
Context targetContext) throws CancelException {
|
||||
boolean ret = false;
|
||||
if(target != null) {
|
||||
CGNode callee = cg.findOrCreateNode(target, targetContext);
|
||||
// add nodes first, to be on the safe side
|
||||
cg.addNode(caller); cg.addNode(callee);
|
||||
cg.addNode(caller);
|
||||
cg.addNode(callee);
|
||||
// add callee as successor of caller
|
||||
cg.addEdge(caller, callee);
|
||||
// add as site-specific target
|
||||
caller.addTarget(site, callee);
|
||||
ret = !cg.getPossibleTargets(caller, site).contains(callee);
|
||||
if (ret) {
|
||||
cg.addEdge(caller, callee);
|
||||
caller.addTarget(site, callee);
|
||||
}
|
||||
}
|
||||
return target;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -211,10 +224,10 @@ public abstract class FieldBasedCallGraphBuilder {
|
|||
* FuncVertex nodes for the reflectively-invoked methods
|
||||
* @throws CancelException
|
||||
*/
|
||||
private Collection<FuncVertex> getReflectiveTargets(FlowGraph flowGraph, CallVertex callVertex, IProgressMonitor monitor) throws CancelException {
|
||||
private OrdinalSet<FuncVertex> getReflectiveTargets(FlowGraph flowGraph, CallVertex callVertex, IProgressMonitor monitor) throws CancelException {
|
||||
SSAAbstractInvokeInstruction invoke = callVertex.getInstruction();
|
||||
VarVertex functionParam = flowGraph.getVertexFactory().makeVarVertex(callVertex.getCaller(), invoke.getUse(1));
|
||||
return Util.filterByType(flowGraph.getReachingSet(functionParam, monitor), FuncVertex.class);
|
||||
return flowGraph.getReachingSet(functionParam, monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,14 +239,13 @@ public abstract class FieldBasedCallGraphBuilder {
|
|||
|
||||
// find all pairs <call, func> such that call is reachable from func in the flow graph
|
||||
for(final CallVertex callVertex : factory.getCallVertices()) {
|
||||
for(Vertex v : flowgraph.getReachingSet(callVertex, monitor)) {
|
||||
v.accept(new AbstractVertexVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitFuncVertex(FuncVertex funcVertex) {
|
||||
result.add(Pair.make(callVertex, funcVertex));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (callVertex.getCaller().getFullName().contains("string_ctor")) {
|
||||
System.err.println(callVertex.getCaller().getFullName());
|
||||
System.err.println(callVertex.getInstruction());
|
||||
System.err.println(flowgraph.getReachingSet(callVertex, monitor));
|
||||
}
|
||||
for(FuncVertex funcVertex : flowgraph.getReachingSet(callVertex, monitor)) {
|
||||
result.add(Pair.make(callVertex, funcVertex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ public class JSMethodInstructionVisitor extends JSAbstractInstructionVisitor {
|
|||
if(fndef instanceof AstGlobalRead) {
|
||||
AstGlobalRead agr = (AstGlobalRead)fndef;
|
||||
if(agr.getGlobalName().equals("global Function")) {
|
||||
if(invk.getNumberOfParameters() == 0)
|
||||
if(invk.getNumberOfParameters() < 2)
|
||||
return false;
|
||||
// this may be a genuine use of "new Function()", not a declaration/expression
|
||||
if(!symtab.isStringConstant(invk.getUse(1)))
|
||||
|
|
|
@ -13,11 +13,9 @@ package com.ibm.wala.cast.js.callgraph.fieldbased;
|
|||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraph;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraphBuilder;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.CallVertex;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
|
||||
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.js.ipa.callgraph.JSAnalysisOptions;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
||||
|
@ -30,7 +28,6 @@ import com.ibm.wala.util.MonitorUtil;
|
|||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.collections.Util;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
|
||||
/**
|
||||
|
@ -53,8 +50,7 @@ public class OptimisticCallgraphBuilder extends FieldBasedCallGraphBuilder {
|
|||
|
||||
@Override
|
||||
public FlowGraph buildFlowGraph(IProgressMonitor monitor) throws CancelException {
|
||||
FlowGraphBuilder builder = new FlowGraphBuilder(cha, cache);
|
||||
FlowGraph flowgraph = builder.buildFlowGraph();
|
||||
FlowGraph flowgraph = flowGraphFactory();
|
||||
|
||||
// keep track of which call edges we already know about
|
||||
Set<Pair<CallVertex, FuncVertex>> knownEdges = HashSetFactory.make();
|
||||
|
@ -99,11 +95,13 @@ public class OptimisticCallgraphBuilder extends FieldBasedCallGraphBuilder {
|
|||
JavaScriptInvoke invk = c.getInstruction();
|
||||
FuncVertex caller = c.getCaller();
|
||||
|
||||
for(int i=1;i<invk.getNumberOfParameters();++i)
|
||||
for(int i=1;i<invk.getNumberOfParameters();++i) {
|
||||
// only flow receiver into 'this' if invk is, in fact, a method call
|
||||
flowgraph.addEdge(factory.makeVarVertex(caller, invk.getUse(i)), factory.makeArgVertex(callee));
|
||||
if(i > 1 || invk.getDeclaredTarget().equals(JavaScriptMethods.dispatchReference))
|
||||
flowgraph.addEdge(factory.makeVarVertex(caller, invk.getUse(i)), factory.makeParamVertex(callee, i-1));
|
||||
|
||||
}
|
||||
|
||||
// flow from return vertex to result vertex
|
||||
flowgraph.addEdge(factory.makeRetVertex(callee), factory.makeVarVertex(caller, invk.getDef()));
|
||||
}
|
||||
|
@ -116,8 +114,7 @@ public class OptimisticCallgraphBuilder extends FieldBasedCallGraphBuilder {
|
|||
JavaScriptInvoke invk = c.getInstruction();
|
||||
|
||||
VarVertex receiverVertex = factory.makeVarVertex(caller, invk.getUse(1));
|
||||
OrdinalSet<Vertex> reachingSet = flowgraph.getReachingSet(receiverVertex, monitor);
|
||||
Set<FuncVertex> realCallees = Util.filterByType(reachingSet, FuncVertex.class);
|
||||
OrdinalSet<FuncVertex> realCallees = flowgraph.getReachingSet(receiverVertex, monitor);
|
||||
for(FuncVertex realCallee: realCallees) {
|
||||
// flow from arguments to parameters
|
||||
for(int i=2;i<invk.getNumberOfParameters();++i)
|
||||
|
|
|
@ -13,11 +13,11 @@ package com.ibm.wala.cast.js.callgraph.fieldbased;
|
|||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraph;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.FlowGraphBuilder;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.VertexFactory;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.loader.AstMethod;
|
||||
import com.ibm.wala.cast.types.AstMethodReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
|
@ -46,17 +46,20 @@ public class PessimisticCallGraphBuilder extends FieldBasedCallGraphBuilder {
|
|||
|
||||
@Override
|
||||
public FlowGraph buildFlowGraph(IProgressMonitor monitor) {
|
||||
FlowGraphBuilder builder = new FlowGraphBuilder(cha, cache);
|
||||
FlowGraph flowgraph = builder.buildFlowGraph();
|
||||
resolveLocalCalls(flowgraph);
|
||||
FlowGraph flowgraph = flowGraphFactory();
|
||||
resolveLocalCalls(flowgraph);
|
||||
return flowgraph;
|
||||
}
|
||||
|
||||
protected boolean filterFunction(IMethod function) {
|
||||
return function.getDescriptor().equals(AstMethodReference.fnDesc);
|
||||
}
|
||||
|
||||
// add inter-procedural flow for local calls
|
||||
private void resolveLocalCalls(FlowGraph flowgraph) {
|
||||
for(IClass klass : cha) {
|
||||
for(IMethod method : klass.getDeclaredMethods()) {
|
||||
if(method.getDescriptor().equals(AstMethodReference.fnDesc)) {
|
||||
if (filterFunction(method)) {
|
||||
IR ir = cache.getIR(method);
|
||||
ir.visitAllInstructions(new LocalCallSSAVisitor(method, ir.getSymbolTable(), cache.getDefUse(ir), flowgraph));
|
||||
}
|
||||
|
@ -92,6 +95,10 @@ public class PessimisticCallGraphBuilder extends FieldBasedCallGraphBuilder {
|
|||
// the name of the function
|
||||
String fnName = symtab.getStringValue(invk.getUse(1));
|
||||
IClass fnClass = cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fnName));
|
||||
if (fnClass == null) {
|
||||
System.err.println("cannot find " + fnName + " at " + ((AstMethod)method).getSourcePosition());
|
||||
return;
|
||||
}
|
||||
IMethod fn = fnClass.getMethod(AstMethodReference.fnSelector);
|
||||
FuncVertex callee = factory.makeFuncVertex(fnClass);
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ public class WorklistBasedOptimisticCallgraphBuilder extends FieldBasedCallGraph
|
|||
|
||||
for(int i=1;i<invk.getNumberOfParameters();++i) {
|
||||
// only flow receiver into 'this' if invk is, in fact, a method call
|
||||
flowgraph.addEdge(factory.makeVarVertex(caller, invk.getUse(i)), factory.makeArgVertex(callee));
|
||||
if(i > 1 || invk.getDeclaredTarget().equals(JavaScriptMethods.dispatchReference))
|
||||
addFlowEdge(flowgraph, factory.makeVarVertex(caller, invk.getUse(i)), factory.makeParamVertex(callee, i-1), worklist);
|
||||
}
|
||||
|
|
|
@ -10,16 +10,27 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.analysis.pointers.HeapGraph;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.AbstractVertexVisitor;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.FuncVertex;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.UnknownVertex;
|
||||
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.ipa.callgraph.CGNode;
|
||||
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.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.Predicate;
|
||||
import com.ibm.wala.util.collections.IndiscriminateFilter;
|
||||
import com.ibm.wala.util.collections.Filter;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.GraphReachability;
|
||||
import com.ibm.wala.util.graph.GraphSlicer;
|
||||
|
@ -27,6 +38,7 @@ import com.ibm.wala.util.graph.NumberedGraph;
|
|||
import com.ibm.wala.util.graph.impl.InvertedGraph;
|
||||
import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph;
|
||||
import com.ibm.wala.util.intset.OrdinalSet;
|
||||
import com.ibm.wala.util.intset.OrdinalSetMapping;
|
||||
|
||||
/**
|
||||
* A flow graph models data flow between vertices representing local variables, properties,
|
||||
|
@ -43,7 +55,7 @@ public class FlowGraph implements Iterable<Vertex> {
|
|||
|
||||
// the transitive closure of the inverse of this.graph,
|
||||
// but without paths going through the Unknown vertex
|
||||
private GraphReachability<Vertex> optimistic_closure;
|
||||
private GraphReachability<Vertex,FuncVertex> optimistic_closure;
|
||||
|
||||
public FlowGraph() {
|
||||
this.graph = new SlowSparseNumberedGraph<Vertex>(1);
|
||||
|
@ -74,8 +86,17 @@ public class FlowGraph implements Iterable<Vertex> {
|
|||
});
|
||||
|
||||
// compute transitive closure
|
||||
optimistic_closure = new GraphReachability<Vertex>(new InvertedGraph<Vertex>(pruned_flowgraph),
|
||||
IndiscriminateFilter.singleton());
|
||||
optimistic_closure =
|
||||
new GraphReachability<Vertex,FuncVertex>(
|
||||
new InvertedGraph<Vertex>(pruned_flowgraph),
|
||||
new Filter<Vertex>() {
|
||||
@Override
|
||||
public boolean accepts(Vertex o) {
|
||||
return o instanceof FuncVertex;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
optimistic_closure.solve(monitor);
|
||||
}
|
||||
|
||||
|
@ -103,7 +124,7 @@ public class FlowGraph implements Iterable<Vertex> {
|
|||
* Computes the set of vertices that may reach <code>dest</code> along paths not containing an
|
||||
* {@link UnknownVertex}.
|
||||
*/
|
||||
public OrdinalSet<Vertex> getReachingSet(Vertex dest, IProgressMonitor monitor) throws CancelException {
|
||||
public OrdinalSet<FuncVertex> getReachingSet(Vertex dest, IProgressMonitor monitor) throws CancelException {
|
||||
if(!graph.containsNode(dest))
|
||||
return OrdinalSet.empty();
|
||||
|
||||
|
@ -119,4 +140,68 @@ public class FlowGraph implements Iterable<Vertex> {
|
|||
public Iterator<Vertex> iterator() {
|
||||
return graph.iterator();
|
||||
}
|
||||
|
||||
public PointerAnalysis getPointerAnalysis(final IProgressMonitor monitor) {
|
||||
return new PointerAnalysis() {
|
||||
|
||||
@Override
|
||||
public OrdinalSet<? extends InstanceKey> getPointsToSet(PointerKey key) {
|
||||
if (key instanceof LocalPointerKey) {
|
||||
CGNode node = ((LocalPointerKey)key).getNode();
|
||||
FuncVertex fn = factory.makeFuncVertex(node.getMethod().getDeclaringClass());
|
||||
int vn = ((LocalPointerKey)key).getValueNumber();
|
||||
VarVertex v = factory.makeVarVertex(fn, vn);
|
||||
try {
|
||||
return getReachingSet(v, monitor);
|
||||
} catch (CancelException e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OrdinalSetMapping<InstanceKey> getInstanceKeyMapping() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<PointerKey> getPointerKeys() {
|
||||
// TODO Auto-generated method stub
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeapGraph getHeapGraph() {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClassHierarchy getClassHierarchy() {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
|||
import com.ibm.wala.cast.js.ssa.PrototypeLookup;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptMethods;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.js.util.Util;
|
||||
import com.ibm.wala.cast.loader.AstMethod;
|
||||
import com.ibm.wala.cast.loader.AstMethod.LexicalInformation;
|
||||
import com.ibm.wala.cast.types.AstMethodReference;
|
||||
|
@ -79,36 +80,45 @@ public class FlowGraphBuilder {
|
|||
|
||||
addPrimitives(flowgraph);
|
||||
|
||||
for(IClass klass : cha) {
|
||||
for(IMethod method : klass.getDeclaredMethods()) {
|
||||
if(method.getDescriptor().equals(AstMethodReference.fnDesc)) {
|
||||
IR ir = cache.getIR(method);
|
||||
FlowGraphSSAVisitor visitor = new FlowGraphSSAVisitor(ir, flowgraph);
|
||||
|
||||
// first visit normal instructions
|
||||
SSAInstruction[] normalInstructions = ir.getInstructions();
|
||||
for(int i=0;i<normalInstructions.length;++i)
|
||||
if(normalInstructions[i] != null) {
|
||||
visitor.instructionIndex = i;
|
||||
normalInstructions[i].visit(visitor);
|
||||
}
|
||||
|
||||
// now visit phis and catches
|
||||
visitor.instructionIndex = -1;
|
||||
for(Iterator<? extends SSAInstruction> iter=ir.iteratePhis();iter.hasNext();)
|
||||
iter.next().visit(visitor);
|
||||
|
||||
for(Iterator<SSAInstruction> iter=ir.iterateCatchInstructions();iter.hasNext();)
|
||||
iter.next().visit(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
visitProgram(flowgraph);
|
||||
|
||||
return flowgraph;
|
||||
}
|
||||
|
||||
protected void visitProgram(FlowGraph flowgraph) {
|
||||
for(IClass klass : cha) {
|
||||
for(IMethod method : klass.getDeclaredMethods()) {
|
||||
if(method.getDescriptor().equals(AstMethodReference.fnDesc))
|
||||
visitFunction(flowgraph, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void visitFunction(FlowGraph flowgraph, IMethod method) {
|
||||
{
|
||||
IR ir = cache.getIR(method);
|
||||
FlowGraphSSAVisitor visitor = new FlowGraphSSAVisitor(ir, flowgraph);
|
||||
|
||||
// first visit normal instructions
|
||||
SSAInstruction[] normalInstructions = ir.getInstructions();
|
||||
for(int i=0;i<normalInstructions.length;++i)
|
||||
if(normalInstructions[i] != null) {
|
||||
visitor.instructionIndex = i;
|
||||
normalInstructions[i].visit(visitor);
|
||||
}
|
||||
|
||||
// now visit phis and catches
|
||||
visitor.instructionIndex = -1;
|
||||
for(Iterator<? extends SSAInstruction> iter=ir.iteratePhis();iter.hasNext();)
|
||||
iter.next().visit(visitor);
|
||||
|
||||
for(Iterator<SSAInstruction> iter=ir.iterateCatchInstructions();iter.hasNext();)
|
||||
iter.next().visit(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
// primitive functions that are treated specially
|
||||
private static String[] primitiveFunctions = { "Object", "Function", "Array", "String", "Number", "RegExp" };
|
||||
private static String[] primitiveFunctions = { "Object", "Function", "Array", "StringObject", "NumberObject", "BooleanObject", "RegExp" };
|
||||
|
||||
/**
|
||||
* Add flows from the special primitive functions to the corresponding global variables.
|
||||
|
@ -120,7 +130,8 @@ public class FlowGraphBuilder {
|
|||
for(String pf : primitiveFunctions) {
|
||||
TypeReference typeref = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, "L" + pf);
|
||||
IClass klass = cha.lookupClass(typeref);
|
||||
flowgraph.addEdge(factory.makeFuncVertex(klass), factory.makePropVertex(pf));
|
||||
String prop = pf.endsWith("Object")? pf.substring(0, pf.length() - 6): pf;
|
||||
flowgraph.addEdge(factory.makeFuncVertex(klass), factory.makePropVertex(prop));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +289,14 @@ public class FlowGraphBuilder {
|
|||
w = factory.makeVarVertex(func, pr.getDef());
|
||||
flowgraph.addEdge(v, w);
|
||||
}
|
||||
|
||||
IntSet argVns = Util.getArgumentsArrayVns(ir, du);
|
||||
if (argVns.contains(pr.getObjectRef())) {
|
||||
Vertex v = factory.makeArgVertex(func),
|
||||
w = factory.makeVarVertex(func, pr.getDef());
|
||||
flowgraph.addEdge(v, w);
|
||||
}
|
||||
|
||||
handleLexicalDef(pr.getDef());
|
||||
}
|
||||
|
||||
|
@ -324,6 +343,10 @@ public class FlowGraphBuilder {
|
|||
|
||||
// find the function being defined here
|
||||
IClass klass = cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fn_name));
|
||||
if (klass == null) {
|
||||
System.err.println("cannot find " + fn_name + " at " + ((AstMethod)ir.getMethod()).getSourcePosition(ir.getCallInstructionIndices(invk.getCallSite()).intIterator().next()));
|
||||
return;
|
||||
}
|
||||
IMethod fn = klass.getMethod(AstMethodReference.fnSelector);
|
||||
FuncVertex fnVertex = factory.makeFuncVertex(klass);
|
||||
|
||||
|
|
|
@ -50,6 +50,11 @@ public class AbstractVertexVisitor<T> implements VertexVisitor<T> {
|
|||
return visitVertex(retVertex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visitArgVertex(ArgVertex argVertex) {
|
||||
return visitVertex(argVertex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visitCalleeVertex(CallVertex calleeVertex) {
|
||||
return visitVertex(calleeVertex);
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2012 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.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
|
||||
/**
|
||||
* A return vertex represents the 'arguments' array of a given function.
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public class ArgVertex extends Vertex {
|
||||
private final FuncVertex func;
|
||||
|
||||
ArgVertex(FuncVertex func) {
|
||||
this.func = func;
|
||||
}
|
||||
|
||||
public FuncVertex getFunc() {
|
||||
return func;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(VertexVisitor<T> visitor) {
|
||||
return visitor.visitArgVertex(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Args(" + func + ")";
|
||||
}
|
||||
}
|
|
@ -10,7 +10,14 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
|
||||
/**
|
||||
* A function vertex represents a function object (or, more precisely, all function objects
|
||||
|
@ -18,7 +25,7 @@ import com.ibm.wala.classLoader.IClass;
|
|||
*
|
||||
* @author mschaefer
|
||||
*/
|
||||
public class FuncVertex extends Vertex {
|
||||
public class FuncVertex extends Vertex implements InstanceKey {
|
||||
// the IClass representing this function in the class hierarchy
|
||||
private final IClass klass;
|
||||
|
||||
|
@ -26,7 +33,8 @@ public class FuncVertex extends Vertex {
|
|||
this.klass = method;
|
||||
}
|
||||
|
||||
public IClass getIClass() {
|
||||
@Override
|
||||
public IClass getConcreteType() {
|
||||
return klass;
|
||||
}
|
||||
|
||||
|
@ -44,4 +52,10 @@ public class FuncVertex extends Vertex {
|
|||
String methodName = klass.getName().toString();
|
||||
return "Func(" + methodName.substring(methodName.lastIndexOf('/')+1) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Pair<CGNode, NewSiteReference>> getCreationSites(CallGraph CG) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ public class VertexFactory {
|
|||
private final Map<Pair<FuncVertex, Integer>, ParamVertex> paramVertexCache = HashMapFactory.make();
|
||||
private final Map<String, PropVertex> propVertexCache = HashMapFactory.make();
|
||||
private final Map<FuncVertex, RetVertex> retVertexCache = HashMapFactory.make();
|
||||
private final Map<FuncVertex, ArgVertex> argVertexCache = HashMapFactory.make();
|
||||
private final Map<Pair<FuncVertex, Integer>, VarVertex> varVertexCache = HashMapFactory.make();
|
||||
private final Map<Pair<String, String>, LexicalVarVertex> lexicalAccessVertexCache = HashMapFactory.make();
|
||||
|
||||
|
@ -84,6 +85,13 @@ public class VertexFactory {
|
|||
return value;
|
||||
}
|
||||
|
||||
public ArgVertex makeArgVertex(FuncVertex func) {
|
||||
ArgVertex value = argVertexCache.get(func);
|
||||
if(value == null)
|
||||
argVertexCache.put(func, value = new ArgVertex(func));
|
||||
return value;
|
||||
}
|
||||
|
||||
public UnknownVertex makeUnknownVertex() {
|
||||
return UnknownVertex.INSTANCE;
|
||||
}
|
||||
|
|
|
@ -20,4 +20,5 @@ public interface VertexVisitor<T> {
|
|||
public abstract T visitRetVertex(RetVertex retVertex);
|
||||
public abstract T visitCalleeVertex(CallVertex calleeVertex);
|
||||
public abstract T visitLexicalAccessVertex(LexicalVarVertex lexicalAccessVertex);
|
||||
public abstract T visitArgVertex(ArgVertex argVertex);
|
||||
}
|
||||
|
|
|
@ -53,9 +53,9 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
|||
String v = e.getValue().fst;
|
||||
if (v != null && v.startsWith("javascript:")) {
|
||||
try {
|
||||
entrypointRegion.println(" " + v.substring(11), e.getValue().snd, new URL(tag.getElementPosition().getURL().toString() + "#" + a));
|
||||
entrypointRegion.println(" " + v.substring(11), e.getValue().snd, new URL(tag.getElementPosition().getURL().toString() + "#" + a), true);
|
||||
} catch (MalformedURLException ex) {
|
||||
entrypointRegion.println(v.substring(11), e.getValue().snd, entrypointUrl);
|
||||
entrypointRegion.println(v.substring(11), e.getValue().snd, entrypointUrl, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
|||
if (pos == null){
|
||||
domRegion.println(indentedLine.toString());
|
||||
} else {
|
||||
domRegion.println(indentedLine.toString(), pos, entrypointUrl);
|
||||
domRegion.println(indentedLine.toString(), pos, entrypointUrl, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
|||
}
|
||||
|
||||
private String makeRef(String object, String property) {
|
||||
assert object != null && property != null;
|
||||
return object + "[\"" + property + "\"]";
|
||||
}
|
||||
|
||||
|
@ -135,6 +136,7 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
|||
}
|
||||
}
|
||||
|
||||
assert varName != null && !"".equals(varName);
|
||||
printlnIndented(varName + " = this;", tag);
|
||||
printlnIndented("document." + varName + " = this;", tag);
|
||||
printlnIndented("parent.appendChild(this);", tag);
|
||||
|
@ -149,18 +151,18 @@ public class DefaultSourceExtractor extends DomLessSourceExtractor{
|
|||
//There should probably be more checking to see what the attributes are since we allow things like: ; to be used as attributes now.
|
||||
if(attr.length() >= 2 && attr.substring(0,2).equals("on")) {
|
||||
printlnIndented(varName + "." + attr + " = function " + tag.getName().toLowerCase() + "_" + attr + "(event) {" + value + "};", tag);
|
||||
entrypointRegion.println(varName2 + "." + attr + "(null);", tag.getElementPosition(), entrypointUrl);
|
||||
entrypointRegion.println(varName2 + "." + attr + "(null);", tag.getElementPosition(), entrypointUrl, false);
|
||||
} else if (value != null) {
|
||||
if (value.indexOf('\'') > 0) {
|
||||
value = value.replaceAll("\\'", "\\\\'");
|
||||
}
|
||||
if (value.indexOf('\n') > 0) {
|
||||
value = value.replaceAll("\\n", "\\\\n");
|
||||
}
|
||||
|
||||
Pair<String, Character> x = quotify(value);
|
||||
value = x.fst;
|
||||
char quote = x.snd;
|
||||
|
||||
if (attr.equals(attr.toUpperCase())) {
|
||||
attr = attr.toLowerCase();
|
||||
}
|
||||
printlnIndented(varName + "['" + attr + "'] = '" + value + "';", tag);
|
||||
|
||||
printlnIndented(varName + "['" + attr + "'] = " + quote + value + quote + ";", tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,11 @@ package com.ibm.wala.cast.js.html;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
|
@ -28,9 +30,15 @@ import com.ibm.wala.cast.js.html.jericho.JerichoHtmlParser;
|
|||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
|
||||
|
||||
/**
|
||||
* extracts JavaScript source code from HTML, with no model of the actual
|
||||
* DOM data structure
|
||||
*/
|
||||
public class DomLessSourceExtractor extends JSSourceExtractor {
|
||||
private static final Pattern LEGAL_JS_IDENTIFIER_REGEXP = Pattern.compile("[a-zA-Z$_][a-zA-Z\\d$_]*");
|
||||
private static final Pattern LEGAL_JS_IDENTIFIER_REGEXP = Pattern.compile("^[a-zA-Z$_][a-zA-Z\\d$_]*$");
|
||||
private static final Pattern LEGAL_JS_KEYWORD_REGEXP = Pattern.compile("^((break)|(case)|(catch)|(continue)|(debugger)|(default)|(delete)|(do)|(else)|(finally)|(for)|(function)|(if)|(in)|(instanceof)|(new)|(return)|(switch)|(this)|(throw)|(try)|(typeof)|(var)|(void)|(while)|(with))$");
|
||||
|
||||
|
||||
protected interface IGeneratorCallback extends IHtmlCallback {
|
||||
void writeToFinalRegion(SourceRegion finalRegion);
|
||||
}
|
||||
|
@ -57,8 +65,14 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
this.scriptRegion = new SourceRegion();
|
||||
this.domRegion = new SourceRegion();
|
||||
this.entrypointRegion = new SourceRegion();
|
||||
addDefaultHandlerInvocations();
|
||||
}
|
||||
|
||||
private void addDefaultHandlerInvocations() {
|
||||
// always invoke window.onload
|
||||
entrypointRegion.println("window.onload();");
|
||||
}
|
||||
|
||||
protected Position makePos(int lineNumber, ITag governingTag) {
|
||||
return makePos(entrypointUrl, lineNumber, governingTag);
|
||||
}
|
||||
|
@ -91,7 +105,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
scriptRegion.println(text, currentScriptTag.getContentPosition(), url);
|
||||
scriptRegion.println(text, currentScriptTag.getContentPosition(), url, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +120,12 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
handleDOM(tag);
|
||||
}
|
||||
|
||||
private boolean isUsableIdentifier(String x) {
|
||||
return x != null &&
|
||||
LEGAL_JS_IDENTIFIER_REGEXP.matcher(x).matches() &&
|
||||
!LEGAL_JS_KEYWORD_REGEXP.matcher(x).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Model the HTML DOM
|
||||
*
|
||||
|
@ -117,7 +137,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
// running counter
|
||||
Pair<String,Position> idAttribute = tag.getAttributeByName("id");
|
||||
String funcName;
|
||||
if (idAttribute != null && LEGAL_JS_IDENTIFIER_REGEXP.matcher(idAttribute.fst).matches()) {
|
||||
if (idAttribute != null && isUsableIdentifier(idAttribute.fst)) {
|
||||
funcName = idAttribute.fst;
|
||||
} else {
|
||||
funcName = "node" + (nodeCounter++);
|
||||
|
@ -149,16 +169,35 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
String fName = tag.getName().toLowerCase() + "_" + attName + "_" + funcName;
|
||||
String signatureLine = "function " + fName + "(event) {";
|
||||
// Defines the function
|
||||
domRegion.println(signatureLine + "\n" + extructJS(attValue) + "\n}", pos, url);
|
||||
domRegion.println(signatureLine + "\n" + extructJS(attValue) + "\n}", pos, url, true);
|
||||
// Run it
|
||||
entrypointRegion.println("\t" + fName + "(null);", pos, url);
|
||||
entrypointRegion.println("\t" + fName + "(null);", pos, url, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Pair<String,Character> quotify(String value) {
|
||||
char quote;
|
||||
if (value.indexOf('"') < 0) {
|
||||
quote= '"';
|
||||
} else if (value.indexOf("'") < 0) {
|
||||
quote= '"';
|
||||
} else {
|
||||
quote= '"';
|
||||
value = value.replaceAll("\"", "\\\"");
|
||||
}
|
||||
|
||||
if (value.indexOf('\n') >= 0) {
|
||||
value = value.replaceAll("\n", "\\n");
|
||||
}
|
||||
|
||||
return Pair.make(value, quote);
|
||||
}
|
||||
|
||||
private String extructJS(String attValue) {
|
||||
if (attValue == null){
|
||||
return "";
|
||||
}
|
||||
|
||||
String content;
|
||||
if (attValue.toLowerCase().equals("javascript:")) {
|
||||
content = attValue.substring("javascript:".length());
|
||||
|
@ -171,12 +210,12 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
|
||||
protected void handleScript(ITag tag) {
|
||||
|
||||
Pair<String,Position> value = tag.getAttributeByName("src");
|
||||
Pair<String,Position> content = tag.getAttributeByName("src");
|
||||
|
||||
try {
|
||||
if (value != null) {
|
||||
if (content != null) {
|
||||
// script is out-of-line
|
||||
getScriptFromUrl(value.fst, tag);
|
||||
getScriptFromUrl(content.fst, tag);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
|
@ -187,15 +226,16 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
}
|
||||
|
||||
private void getScriptFromUrl(String urlAsString, ITag scriptTag) throws IOException, MalformedURLException {
|
||||
URL absoluteUrl = UrlManipulator.relativeToAbsoluteUrl(urlAsString, this.entrypointUrl);
|
||||
URL scriptSrc = urlResolver.resolve(absoluteUrl);
|
||||
// URL absoluteUrl = UrlManipulator.relativeToAbsoluteUrl(urlAsString, this.entrypointUrl);
|
||||
// URL scriptSrc = urlResolver.resolve(absoluteUrl);
|
||||
URL scriptSrc = new URL(entrypointUrl, urlAsString);
|
||||
if (scriptSrc == null) { //Error resolving URL
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream scriptInputStream;
|
||||
Reader scriptInputStream;
|
||||
try {
|
||||
scriptInputStream = scriptSrc.openConnection().getInputStream();
|
||||
scriptInputStream = new InputStreamReader(scriptSrc.openConnection().getInputStream());
|
||||
} catch (Exception e) {
|
||||
//it looks like this happens when we can't resolve the url?
|
||||
if (DEBUG) {
|
||||
|
@ -209,13 +249,13 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
BufferedReader scriptReader = null;
|
||||
try {
|
||||
String line;
|
||||
scriptReader = new BufferedReader(new UnicodeReader(scriptInputStream, "UTF8"));
|
||||
scriptReader = new BufferedReader(scriptInputStream);
|
||||
StringBuffer x = new StringBuffer();
|
||||
while ((line = scriptReader.readLine()) != null) {
|
||||
x.append(line).append("\n");
|
||||
}
|
||||
|
||||
scriptRegion.println(x.toString(), scriptTag.getElementPosition(), scriptSrc);
|
||||
scriptRegion.println(x.toString(), scriptTag.getElementPosition(), scriptSrc, false);
|
||||
|
||||
} finally {
|
||||
if (scriptReader != null) {
|
||||
|
@ -260,7 +300,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
public Set<MappedSourceModule> extractSources(URL entrypointUrl, IHtmlParser htmlParser, IUrlResolver urlResolver)
|
||||
throws IOException, Error {
|
||||
|
||||
InputStream inputStreamReader = WebUtil.getStream(entrypointUrl);
|
||||
Reader inputStreamReader = WebUtil.getStream(entrypointUrl);
|
||||
IGeneratorCallback htmlCallback = createHtmlCallback(entrypointUrl, urlResolver);
|
||||
htmlParser.parse(entrypointUrl, inputStreamReader, htmlCallback, entrypointUrl.getFile());
|
||||
|
||||
|
@ -270,7 +310,7 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
// writing the final region into one SourceFileModule.
|
||||
File outputFile = createOutputFile(entrypointUrl, DELETE_UPON_EXIT, USE_TEMP_NAME);
|
||||
tempFile = outputFile;
|
||||
FileMapping fileMapping = finalRegion.writeToFile(new PrintStream(outputFile));
|
||||
FileMapping fileMapping = finalRegion.writeToFile(new PrintWriter(new FileWriter(outputFile)));
|
||||
if (fileMapping == null) {
|
||||
fileMapping = new EmptyFileMapping();
|
||||
}
|
||||
|
@ -284,10 +324,14 @@ public class DomLessSourceExtractor extends JSSourceExtractor {
|
|||
|
||||
private File createOutputFile(URL url, boolean delete, boolean useTempName) throws IOException {
|
||||
File outputFile;
|
||||
String fileName = new File(url.getFile()).getName();
|
||||
if (fileName.length() < 5) {
|
||||
fileName = "xxxx" + fileName;
|
||||
}
|
||||
if (useTempName) {
|
||||
outputFile = File.createTempFile(new File(url.getFile()).getName(), ".js");
|
||||
outputFile = File.createTempFile(fileName, ".js");
|
||||
} else {
|
||||
outputFile = new File(new File(url.getFile()).getName());
|
||||
outputFile = new File(fileName);
|
||||
}
|
||||
if (outputFile.exists()){
|
||||
outputFile.delete();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.html;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.TranslatorToCAst.Error;
|
||||
|
@ -29,6 +29,6 @@ public interface IHtmlParser {
|
|||
* @param fileName
|
||||
* @throws Error
|
||||
*/
|
||||
public void parse(URL url, InputStream reader, IHtmlCallback callback, String fileName) throws Error;
|
||||
public void parse(URL url, Reader reader, IHtmlCallback callback, String fileName) throws Error;
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
package com.ibm.wala.cast.js.html;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.js.html.RangeFileMapping.Range;
|
||||
|
@ -69,8 +69,8 @@ public class NestedRangeMapping implements FileMapping {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return pos.getInputStream();
|
||||
public Reader getReader() throws IOException {
|
||||
return pos.getReader();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
package com.ibm.wala.cast.js.html;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
|
@ -19,7 +20,7 @@ import com.ibm.wala.cast.tree.impl.AbstractSourcePosition;
|
|||
|
||||
public class RangeFileMapping implements FileMapping {
|
||||
|
||||
public static class Range {
|
||||
public final static class Range {
|
||||
private final int rangeStart;
|
||||
private final int rangeEnd;
|
||||
private final int rangeStartingLine;
|
||||
|
@ -113,9 +114,9 @@ public class RangeFileMapping implements FileMapping {
|
|||
return includedURL;
|
||||
}
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return includedURL.openConnection().getInputStream();
|
||||
}
|
||||
public Reader getReader() throws IOException {
|
||||
return RangeFileMapping.this.getInputStream();
|
||||
}
|
||||
@Override
|
||||
public Position getIncludePosition() {
|
||||
return includePosition;
|
||||
|
@ -132,5 +133,8 @@ public class RangeFileMapping implements FileMapping {
|
|||
}
|
||||
}
|
||||
|
||||
public Reader getInputStream() throws IOException {
|
||||
return new InputStreamReader(includedURL.openStream());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.html;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
|
@ -33,15 +36,25 @@ public class SourceRegion {
|
|||
public SourceRegion() {
|
||||
}
|
||||
|
||||
public void print(String text, Position originalPos, URL url){
|
||||
public void print(final String text, Position originalPos, URL url, boolean bogusURL){
|
||||
int startOffset = source.length();
|
||||
source.append(text);
|
||||
source.append(text);
|
||||
int endOffset = source.length();
|
||||
|
||||
int numberOfLineDrops = getNumberOfLineDrops(text);
|
||||
|
||||
if (originalPos != null) {
|
||||
RangeFileMapping map = new RangeFileMapping(startOffset, endOffset, currentLine, currentLine+numberOfLineDrops, originalPos, url);
|
||||
RangeFileMapping map;
|
||||
if (bogusURL) {
|
||||
map = new RangeFileMapping(startOffset, endOffset, currentLine, currentLine+numberOfLineDrops, originalPos, url) {
|
||||
@Override
|
||||
public Reader getInputStream() throws IOException {
|
||||
return new StringReader(text);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
map = new RangeFileMapping(startOffset, endOffset, currentLine, currentLine+numberOfLineDrops, originalPos, url);
|
||||
}
|
||||
if (fileMapping == null) {
|
||||
fileMapping = map;
|
||||
} else {
|
||||
|
@ -52,20 +65,21 @@ public class SourceRegion {
|
|||
currentLine += numberOfLineDrops;
|
||||
}
|
||||
|
||||
public void println(String text, Position originalPos, URL url){
|
||||
print(text + "\n", originalPos, url);
|
||||
public void println(String text, Position originalPos, URL url, boolean bogusURL){
|
||||
print(text + "\n", originalPos, url, bogusURL);
|
||||
}
|
||||
|
||||
public void print(String text){
|
||||
print(text, null, null);
|
||||
print(text, null, null, true);
|
||||
}
|
||||
|
||||
public void println(String text){
|
||||
print(text + "\n");
|
||||
}
|
||||
|
||||
public FileMapping writeToFile(PrintStream ps){
|
||||
public FileMapping writeToFile(PrintWriter ps){
|
||||
ps.print(source.toString());
|
||||
ps.flush();
|
||||
return fileMapping;
|
||||
}
|
||||
|
||||
|
@ -89,7 +103,7 @@ public class SourceRegion {
|
|||
currentLine += numberOfLineDrops;
|
||||
}
|
||||
|
||||
public void dump(PrintStream ps){
|
||||
public void dump(PrintWriter ps){
|
||||
ps.println(source.toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2002 - 2011 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.html;
|
||||
|
||||
/**
|
||||
http://www.unicode.org/unicode/faq/utf_bom.html
|
||||
BOMs:
|
||||
00 00 FE FF = UTF-32, big-endian
|
||||
FF FE 00 00 = UTF-32, little-endian
|
||||
FE FF = UTF-16, big-endian
|
||||
FF FE = UTF-16, little-endian
|
||||
EF BB BF = UTF-8
|
||||
|
||||
Win2k Notepad:
|
||||
Unicode format = UTF-16LE
|
||||
***/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PushbackInputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* Generic unicode textreader, which will use BOM mark to identify the encoding to be used.
|
||||
*/
|
||||
public class UnicodeReader extends Reader {
|
||||
PushbackInputStream internalIn;
|
||||
|
||||
InputStreamReader internalIn2 = null;
|
||||
|
||||
String defaultEnc;
|
||||
|
||||
private static final int BOM_SIZE = 6;
|
||||
|
||||
/*
|
||||
* Default encoding is used only if BOM is not found. If defaultEncoding is NULL then systemdefault is used.
|
||||
*/
|
||||
public UnicodeReader(InputStream in, String defaultEnc) {
|
||||
internalIn = new PushbackInputStream(in, BOM_SIZE);
|
||||
this.defaultEnc = defaultEnc;
|
||||
}
|
||||
|
||||
public String getDefaultEncoding() {
|
||||
return defaultEnc;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
if (internalIn2 == null)
|
||||
return null;
|
||||
return internalIn2.getEncoding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read-ahead four bytes and check for BOM marks. Extra bytes are unread back to the stream, only BOM bytes are skipped.
|
||||
*/
|
||||
protected void init() throws IOException {
|
||||
if (internalIn2 != null)
|
||||
return;
|
||||
|
||||
String encoding;
|
||||
byte bom[] = new byte[BOM_SIZE];
|
||||
int n, unread;
|
||||
n = internalIn.read(bom, 0, bom.length);
|
||||
|
||||
if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF) && (bom[3] == (byte) 0xEF) && (bom[4] == (byte) 0xBB) && (bom[5] == (byte) 0xBF)) {
|
||||
encoding = "UTF-8";
|
||||
unread = n - 6;
|
||||
} else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
|
||||
encoding = "UTF-8";
|
||||
unread = n - 3;
|
||||
} else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
|
||||
encoding = "UTF-16BE";
|
||||
unread = n - 2;
|
||||
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
|
||||
encoding = "UTF-16LE";
|
||||
unread = n - 2;
|
||||
} else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
|
||||
encoding = "UTF-32BE";
|
||||
unread = n - 4;
|
||||
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
|
||||
encoding = "UTF-32LE";
|
||||
unread = n - 4;
|
||||
} else {
|
||||
// Unicode BOM mark not found, unread all bytes
|
||||
encoding = defaultEnc;
|
||||
unread = n;
|
||||
}
|
||||
// System.out.println("read=" + n + ", unread=" + unread);
|
||||
|
||||
if (unread > 0)
|
||||
internalIn.unread(bom, (n - unread), unread);
|
||||
else if (unread < -1)
|
||||
internalIn.unread(bom, 0, 0);
|
||||
|
||||
// Use given encoding
|
||||
if (encoding == null) {
|
||||
internalIn2 = new InputStreamReader(internalIn);
|
||||
} else {
|
||||
internalIn2 = new InputStreamReader(internalIn, encoding);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
init();
|
||||
internalIn2.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||
init();
|
||||
return internalIn2.read(cbuf, off, len);
|
||||
}
|
||||
|
||||
}
|
|
@ -16,13 +16,17 @@ import com.ibm.wala.cast.js.loader.JavaScriptLoaderFactory;
|
|||
import com.ibm.wala.cast.js.ssa.JSInstructionFactory;
|
||||
import com.ibm.wala.cast.js.translator.JSAstTranslator;
|
||||
import com.ibm.wala.cast.js.translator.JavaScriptTranslatorFactory;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.tree.CAst;
|
||||
import com.ibm.wala.cast.tree.CAstEntity;
|
||||
import com.ibm.wala.cast.tree.CAstNode;
|
||||
import com.ibm.wala.cast.tree.impl.CAstImpl;
|
||||
import com.ibm.wala.cast.tree.impl.CAstOperator;
|
||||
import com.ibm.wala.cast.tree.rewrite.CAstRewriterFactory;
|
||||
import com.ibm.wala.cast.tree.visit.CAstVisitor;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
||||
public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
|
||||
|
||||
|
@ -42,17 +46,21 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
|
|||
return new JSAstTranslator(this) {
|
||||
private final CAst Ast = new CAstImpl();
|
||||
|
||||
private boolean isNestedWithinScriptBody(WalkContext context) {
|
||||
return isScriptBody(context) || context.getName().contains("__WINDOW_MAIN__");
|
||||
}
|
||||
|
||||
private boolean isScriptBody(WalkContext context) {
|
||||
return context.top().getName().equals( "__WINDOW_MAIN__" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doGlobalRead(CAstNode n, WalkContext context, String name) {
|
||||
protected int doGlobalRead(CAstNode n, WalkContext context, String name, TypeReference type) {
|
||||
int result = context.currentScope().allocateTempValue();
|
||||
if (isScriptBody(context) && ! "$$undefined".equals(name) && ! "window".equals(name)) {
|
||||
if (isNestedWithinScriptBody(context) && ! "$$undefined".equals(name) && ! "window".equals(name)) {
|
||||
|
||||
// check if field is defined on 'window'
|
||||
int windowVal = super.doLocalRead(context, "this");
|
||||
int windowVal = isScriptBody(context)? super.doLocalRead(context, "this", JavaScriptTypes.Root): super.doGlobalRead(n, context, "window", type);
|
||||
int isDefined = context.currentScope().allocateTempValue();
|
||||
context.currentScope().getConstantValue(name);
|
||||
doIsFieldDefined(context, isDefined, windowVal, Ast.makeConstant(name));
|
||||
|
@ -73,7 +81,7 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
|
|||
// read global
|
||||
context.cfg().newBlock(false);
|
||||
PreBasicBlock falseB = context.cfg().getCurrentBlock();
|
||||
int sr = super.doGlobalRead(n, context, name);
|
||||
int sr = super.doGlobalRead(n, context, name, type);
|
||||
context.cfg().addInstruction(((JSInstructionFactory) insts).AssignInstruction(context.cfg().getCurrentInstruction(), result, sr));
|
||||
|
||||
// end
|
||||
|
@ -85,19 +93,31 @@ public class WebPageLoaderFactory extends JavaScriptLoaderFactory {
|
|||
return result;
|
||||
|
||||
} else {
|
||||
return super.doGlobalRead(n, context, name);
|
||||
return super.doGlobalRead(n, context, name, type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLocalWrite(WalkContext context, String nm, int rval) {
|
||||
protected void doLocalWrite(WalkContext context, String nm, TypeReference type, int rval) {
|
||||
if (isScriptBody(context)) {
|
||||
int windowVal = super.doLocalRead(context, "this");
|
||||
int windowVal = super.doLocalRead(context, "this", type);
|
||||
context.currentScope().getConstantValue(nm);
|
||||
context.cfg().addInstruction(((JSInstructionFactory) insts).PutInstruction(context.cfg().getCurrentInstruction(), windowVal, rval, nm));
|
||||
}
|
||||
|
||||
super.doLocalWrite(context, nm, rval);
|
||||
super.doLocalWrite(context, nm, type, rval);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void leaveFunctionStmt(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
|
||||
super.leaveFunctionStmt(n, context, visitor);
|
||||
if (isScriptBody(context)) {
|
||||
CAstEntity fn = (CAstEntity) n.getChild(0).getValue();
|
||||
int fnValue = context.currentScope().lookup(fn.getName()).valueNumber();
|
||||
assert fnValue > 0;
|
||||
int windowVal = super.doLocalRead(context, "this", JavaScriptTypes.Function);
|
||||
context.cfg().addInstruction(((JSInstructionFactory) insts).PutInstruction(context.cfg().getCurrentInstruction(), windowVal, fnValue, fn.getName()));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ package com.ibm.wala.cast.js.html;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
@ -45,9 +46,9 @@ public class WebUtil {
|
|||
* such file exists)
|
||||
* @throws Error
|
||||
*/
|
||||
public static Pair<Set<MappedSourceModule>,File> extractScriptFromHTML(URL url) throws Error {
|
||||
public static Pair<Set<MappedSourceModule>,File> extractScriptFromHTML(URL url, boolean useDOMModel) throws Error {
|
||||
try {
|
||||
JSSourceExtractor extractor = new DefaultSourceExtractor();
|
||||
JSSourceExtractor extractor = useDOMModel? new DefaultSourceExtractor(): new DomLessSourceExtractor();
|
||||
Set<MappedSourceModule> sources = extractor.extractSources(url, factory.getParser(), new IdentityUrlResolver());
|
||||
return Pair.make(sources, extractor.getTempFile());
|
||||
} catch (IOException e) {
|
||||
|
@ -56,15 +57,15 @@ public class WebUtil {
|
|||
}
|
||||
|
||||
public static void main(String[] args) throws MalformedURLException, Error {
|
||||
System.err.println(extractScriptFromHTML(new URL(args[0])));
|
||||
System.err.println(extractScriptFromHTML(new URL(args[0]), Boolean.parseBoolean(args[1])));
|
||||
}
|
||||
|
||||
public static InputStream getStream(URL url) throws IOException {
|
||||
public static Reader getStream(URL url) throws IOException {
|
||||
URLConnection conn = url.openConnection();
|
||||
conn.setDefaultUseCaches(false);
|
||||
conn.setUseCaches(false);
|
||||
|
||||
return conn.getInputStream();
|
||||
return new InputStreamReader(conn.getInputStream());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
package com.ibm.wala.cast.js.html.jericho;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -102,7 +102,7 @@ public class JerichoHtmlParser implements IHtmlParser{
|
|||
}
|
||||
|
||||
@Override
|
||||
public void parse(URL url, InputStream reader, IHtmlCallback callback, String fileName) throws TranslatorToCAst.Error {
|
||||
public void parse(URL url, Reader reader, IHtmlCallback callback, String fileName) throws TranslatorToCAst.Error {
|
||||
warnings.clear();
|
||||
Parser parser = new Parser(callback, fileName);
|
||||
Source src;
|
||||
|
@ -115,7 +115,7 @@ public class JerichoHtmlParser implements IHtmlParser{
|
|||
parser.parse(e);
|
||||
}
|
||||
if (! warnings.isEmpty()) {
|
||||
throw new TranslatorToCAst.Error(warnings.iterator().next());
|
||||
throw new TranslatorToCAst.Error(warnings);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error parsing file: " + e.getMessage());
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.html.jericho;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
@ -57,12 +57,14 @@ public class JerichoTag implements ITag {
|
|||
|
||||
@Override
|
||||
public int getFirstCol() {
|
||||
return e.getSource().getRowColumnVector(e.getBegin()).getColumn();
|
||||
return -1;
|
||||
// return e.getSource().getRowColumnVector(e.getBegin()).getColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLastCol() {
|
||||
return e.getSource().getRowColumnVector(e.getEnd()).getColumn();
|
||||
return -1;
|
||||
//return e.getSource().getRowColumnVector(e.getEnd()).getColumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,8 +87,8 @@ public class JerichoTag implements ITag {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FileInputStream(sourceFile);
|
||||
public Reader getReader() throws IOException {
|
||||
return new FileReader(sourceFile);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -122,7 +124,7 @@ public class JerichoTag implements ITag {
|
|||
public Pair<Integer, String> getBodyText() {
|
||||
Segment content = innerElement.getContent();
|
||||
Integer lineNum = innerElement.getSource().getRow(content.getBegin());
|
||||
String body = content.toString();
|
||||
String body = content.toString().replace(content.getSource().getNewLine(), "\n");
|
||||
return Pair.make(lineNum, body);
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ public class ArgumentSpecialization {
|
|||
|
||||
class FixedArgumentsRewriter extends CAstBasicRewriter {
|
||||
private final CAstEntity e;
|
||||
Map<String, CAstNode> argRefs = HashMapFactory.make();
|
||||
private final Map<String, CAstNode> argRefs = HashMapFactory.make();
|
||||
|
||||
public FixedArgumentsRewriter(CAst Ast) {
|
||||
super(Ast, false);
|
||||
|
|
|
@ -106,5 +106,4 @@ public class JSCallGraph extends AstCallGraph {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ public class JSCallGraphUtil extends com.ibm.wala.cast.ipa.callgraph.CAstCallGra
|
|||
return ClassHierarchy.make(scope, loaders, JavaScriptLoader.JS);
|
||||
}
|
||||
|
||||
public static Iterable<Entrypoint> makeScriptRoots(IClassHierarchy cha) {
|
||||
public static JavaScriptEntryPoints makeScriptRoots(IClassHierarchy cha) {
|
||||
return new JavaScriptEntryPoints(cha, cha.getLoader(JavaScriptTypes.jsLoader));
|
||||
}
|
||||
|
||||
|
@ -130,13 +130,9 @@ public class JSCallGraphUtil extends com.ibm.wala.cast.ipa.callgraph.CAstCallGra
|
|||
* funName exactly.
|
||||
*/
|
||||
public static Collection<CGNode> getNodes(CallGraph CG, String funName) {
|
||||
boolean ctor = funName.startsWith("ctor:");
|
||||
boolean suffix = funName.startsWith("suffix:");
|
||||
if (ctor) {
|
||||
TypeReference TR = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, TypeName.string2TypeName("L" + funName.substring(5)));
|
||||
MethodReference MR = JavaScriptMethods.makeCtorReference(TR);
|
||||
return CG.getNodes(MR);
|
||||
} else if (suffix) {
|
||||
|
||||
if (suffix) {
|
||||
Set<CGNode> nodes = new HashSet<CGNode>();
|
||||
String tail = funName.substring(7);
|
||||
for (CGNode n : CG) {
|
||||
|
@ -145,11 +141,24 @@ public class JSCallGraphUtil extends com.ibm.wala.cast.ipa.callgraph.CAstCallGra
|
|||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
MethodReference MR = getMethodReference(funName);
|
||||
|
||||
return CG.getNodes(MR);
|
||||
}
|
||||
|
||||
public static MethodReference getMethodReference(String funName) {
|
||||
boolean ctor = funName.startsWith("ctor:");
|
||||
MethodReference MR;
|
||||
if (ctor) {
|
||||
TypeReference TR = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, TypeName.string2TypeName("L" + funName.substring(5)));
|
||||
MR = JavaScriptMethods.makeCtorReference(TR);
|
||||
} else {
|
||||
TypeReference TR = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, TypeName.string2TypeName("L" + funName));
|
||||
MethodReference MR = AstMethodReference.fnReference(TR);
|
||||
return CG.getNodes(MR);
|
||||
MR = AstMethodReference.fnReference(TR);
|
||||
}
|
||||
return MR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,22 +55,28 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
private final Map<Object, IMethod> constructors = HashMapFactory.make();
|
||||
|
||||
class JavaScriptConstructor extends JavaScriptSummarizedFunction {
|
||||
public static class JavaScriptConstructor extends JavaScriptSummarizedFunction {
|
||||
private final String toStringExtra;
|
||||
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass, String toStringExtra) {
|
||||
private final IClass constructorForType;
|
||||
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass, IClass constructorForType, String toStringExtra) {
|
||||
super(ref, summary, declaringClass);
|
||||
this.toStringExtra = toStringExtra;
|
||||
this.constructorForType = constructorForType;
|
||||
}
|
||||
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass) {
|
||||
this(ref, summary, declaringClass, "");
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass, IClass constructorForType) {
|
||||
this(ref, summary, declaringClass, constructorForType, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<ctor for " + getReference().getDeclaringClass() + toStringExtra + ">";
|
||||
}
|
||||
|
||||
public IClass constructedType() {
|
||||
return constructorForType;
|
||||
}
|
||||
}
|
||||
|
||||
public JavaScriptConstructTargetSelector(IClassHierarchy cha, MethodTargetSelector base) {
|
||||
|
@ -106,7 +112,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
//S.addConstant(9, new ConstantValue("__proto__"));
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cls);
|
||||
}
|
||||
|
||||
private IMethod makeUnaryValueConstructor(IClass cls) {
|
||||
|
@ -131,7 +137,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
//S.addConstant(7, new ConstantValue("__proto__"));
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cls);
|
||||
}
|
||||
|
||||
private IMethod makeValueConstructor(IClass cls, int nargs, Object value) {
|
||||
|
@ -171,7 +177,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
//S.addConstant(6, new ConstantValue("__proto__"));
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Object));
|
||||
}
|
||||
|
||||
private IMethod makeUnaryObjectConstructor(IClass cls) {
|
||||
|
@ -182,7 +188,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 2, false));
|
||||
S.getNextProgramCounter();
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Object));
|
||||
}
|
||||
|
||||
private IMethod makeObjectConstructor(IClass cls, int nargs) {
|
||||
|
@ -234,7 +240,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
//S.addConstant(7, new ConstantValue("__proto__"));
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Array));
|
||||
}
|
||||
|
||||
private IMethod makeArrayContentsConstructor(IClass cls, int nargs) {
|
||||
|
@ -270,7 +276,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
//S.addConstant(vn, new ConstantValue("__proto__"));
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Array));
|
||||
}
|
||||
|
||||
private IMethod makeArrayConstructor(IClass cls, int nargs) {
|
||||
|
@ -291,7 +297,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 2, false));
|
||||
S.getNextProgramCounter();
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.String));
|
||||
}
|
||||
|
||||
private IMethod makeUnaryStringCall(IClass cls) {
|
||||
|
@ -308,7 +314,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
|
||||
S.getNextProgramCounter();
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.String));
|
||||
}
|
||||
|
||||
private IMethod makeStringCall(IClass cls, int nargs) {
|
||||
|
@ -331,7 +337,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 2, false));
|
||||
S.getNextProgramCounter();
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Number));
|
||||
}
|
||||
|
||||
private IMethod makeUnaryNumberCall(IClass cls) {
|
||||
|
@ -348,7 +354,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
|
||||
S.getNextProgramCounter();
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Number));
|
||||
}
|
||||
|
||||
private IMethod makeNumberCall(IClass cls, int nargs) {
|
||||
|
@ -395,9 +401,9 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
//S.addConstant(8, new ConstantValue("__proto__"));
|
||||
|
||||
if (receiver != cls)
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver, "(" + cls.getReference().getName() + ")"));
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver, cls, "(" + cls.getReference().getName() + ")"));
|
||||
else
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver));
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver, cls));
|
||||
}
|
||||
|
||||
private int ctorCount = 0;
|
||||
|
@ -409,11 +415,11 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
return makeFunctionConstructor(cls, cls);
|
||||
} else if (nargs == 1) {
|
||||
if (ST.isStringConstant(callStmt.getUse(1))) {
|
||||
TypeReference ref = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, TypeName.string2TypeName((String) ST
|
||||
TypeReference ref = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, TypeName.string2TypeName(ST
|
||||
.getStringValue(callStmt.getUse(1))));
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println(("ctor type name is " + (String) ST.getStringValue(callStmt.getUse(1))));
|
||||
System.err.println(("ctor type name is " + ST.getStringValue(callStmt.getUse(1))));
|
||||
}
|
||||
|
||||
IClass cls2 = cha.lookupClass(ref);
|
||||
|
@ -511,7 +517,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
//S.addConstant(nargs + 9, new ConstantValue("__proto__"));
|
||||
|
||||
return record(key, new JavaScriptConstructor(ref, S, cls));
|
||||
return record(key, new JavaScriptConstructor(ref, S, cls, cls));
|
||||
}
|
||||
|
||||
private IMethod findOrCreateConstructorMethod(IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass receiver, int nargs) {
|
||||
|
|
|
@ -56,7 +56,7 @@ public class LoadFileTargetSelector implements MethodTargetSelector {
|
|||
Set<String> names = new HashSet<String>();
|
||||
SSAInstruction call = caller.getIR().getInstructions()[caller.getIR().getCallInstructionIndices(site).intIterator().next()];
|
||||
LocalPointerKey fileNameV = new LocalPointerKey(caller, call.getUse(1));
|
||||
OrdinalSet<InstanceKey> ptrs = builder.getPointerAnalysis().getPointsToSet(fileNameV);
|
||||
OrdinalSet<? extends InstanceKey> ptrs = builder.getPointerAnalysis().getPointsToSet(fileNameV);
|
||||
for(InstanceKey k : ptrs) {
|
||||
if (k instanceof ConstantKey) {
|
||||
Object v = ((ConstantKey)k).getValue();
|
||||
|
|
|
@ -262,7 +262,7 @@ public class CorrelationFinder {
|
|||
} else {
|
||||
JavaScriptLoader.addBootstrapFile(WebUtil.preamble);
|
||||
try {
|
||||
scripts = WebUtil.extractScriptFromHTML(url).fst;
|
||||
scripts = WebUtil.extractScriptFromHTML(url, true).fst;
|
||||
} catch (Error e) {
|
||||
e.printStackTrace();
|
||||
assert false : e.warning;
|
||||
|
|
|
@ -39,6 +39,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.JSAstTranslator;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.tree.CAst;
|
||||
import com.ibm.wala.cast.tree.CAstControlFlowMap;
|
||||
|
@ -508,7 +509,7 @@ public class ClosureExtractor extends CAstRewriterExt {
|
|||
}
|
||||
|
||||
// prepend declaration "var <theLocal>;"
|
||||
CAstNode theLocalDecl = Ast.makeNode(DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(theLocal)),
|
||||
CAstNode theLocalDecl = Ast.makeNode(DECL_STMT, Ast.makeConstant(new CAstSymbolImpl(theLocal, JSAstTranslator.Any)),
|
||||
addExnFlow(makeVarRef("$$undefined"), JavaScriptTypes.ReferenceError, entity, context));
|
||||
if(fun_body_stmts.size() > 1) {
|
||||
CAstNode newBlock = Ast.makeNode(BLOCK_STMT, fun_body_stmts.toArray(new CAstNode[0]));
|
||||
|
|
|
@ -233,12 +233,6 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
|||
return new JavaScriptInvoke(iindex, function, results, params, exception, site);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaScriptInvoke Invoke(int iindex, int function, int[] results, int[] params, int exception, CallSiteReference site,
|
||||
Access[] lexicalReads, Access[] lexicalWrites) {
|
||||
return new JavaScriptInvoke(iindex, function, results, params, exception, site, lexicalReads, lexicalWrites);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaScriptInvoke Invoke(int iindex, int function, int result, int[] params, int exception, CallSiteReference site) {
|
||||
return new JavaScriptInvoke(iindex, function, result, params, exception, site);
|
||||
|
@ -347,8 +341,8 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AstLexicalRead LexicalRead(int iindex, int lhs, String definer, String globalName) {
|
||||
return new AstLexicalRead(iindex, lhs, definer, globalName);
|
||||
public AstLexicalRead LexicalRead(int iindex, int lhs, String definer, String globalName, TypeReference type) {
|
||||
return new AstLexicalRead(iindex, lhs, definer, globalName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -362,8 +356,8 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
|||
}
|
||||
|
||||
@Override
|
||||
public AstLexicalWrite LexicalWrite(int iindex, String definer, String globalName, int rhs) {
|
||||
return new AstLexicalWrite(iindex, definer, globalName, rhs);
|
||||
public AstLexicalWrite LexicalWrite(int iindex, String definer, String globalName, TypeReference type, int rhs) {
|
||||
return new AstLexicalWrite(iindex, definer, globalName, type, rhs);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1018,29 +1012,6 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
|||
bootstrapFileNames.add(prologueFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* adds the {@link #bootstrapFileNames bootstrap files} to the list of modules
|
||||
* and then invokes the superclass method
|
||||
*/
|
||||
@Override
|
||||
public void init(List<Module> modules) {
|
||||
|
||||
List<Module> all = new LinkedList<Module>();
|
||||
|
||||
for (final String fn : bootstrapFileNames) {
|
||||
all.add(new SourceURLModule(getClass().getClassLoader().getResource(fn)) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return fn;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
all.addAll(modules);
|
||||
|
||||
super.init(all);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected TranslatorToCAst getTranslatorToCAst(final CAst ast, SourceModule module) {
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
package com.ibm.wala.cast.js.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.ssa.SSAGetInstruction;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
|
@ -26,8 +25,6 @@ public interface JSInstructionFactory extends AstInstructionFactory {
|
|||
|
||||
JavaScriptInvoke Invoke(int iindex, int function, int results[], int[] params, int exception, CallSiteReference site);
|
||||
|
||||
JavaScriptInvoke Invoke(int iindex, int function, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites);
|
||||
|
||||
JavaScriptInvoke Invoke(int iindex, int function, int result, int[] params, int exception, CallSiteReference site);
|
||||
|
||||
JavaScriptInvoke Invoke(int iindex, int function, int[] params, int exception, CallSiteReference site);
|
||||
|
|
|
@ -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 iindex, int function, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads,
|
||||
Access[] lexicalWrites) {
|
||||
super(iindex, results, exception, site, lexicalReads, lexicalWrites);
|
||||
this.function = function;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public JavaScriptInvoke(int iindex, int function, int result, int[] params, int exception, CallSiteReference site) {
|
||||
this(iindex, 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,15 @@ 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(iindex, fn, newLvals, newParams, newExp, site, reads, writes);
|
||||
return ((JSInstructionFactory)insts).Invoke(iindex, fn, newLvals, newParams, newExp, site);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getNumberOfUses() {
|
||||
return getNumberOfParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,30 +116,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 +134,6 @@ public class JavaScriptInvoke extends AbstractLexicalInvoke {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.domo.ssa.Instruction#getUse(int)
|
||||
*/
|
||||
@Override
|
||||
public int getUse(int j) {
|
||||
if (j == 0)
|
||||
|
|
|
@ -10,13 +10,18 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.translator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
||||
import com.ibm.wala.cast.js.loader.JSCallSiteReference;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||
import com.ibm.wala.cast.js.ssa.JSInstructionFactory;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInstanceOf;
|
||||
import com.ibm.wala.cast.js.ssa.PrototypeLookup;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptMethods;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptTypes;
|
||||
import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation;
|
||||
|
@ -30,6 +35,8 @@ import com.ibm.wala.cast.types.AstMethodReference;
|
|||
import com.ibm.wala.cfg.AbstractCFG;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
|
@ -75,10 +82,29 @@ public class JSAstTranslator extends AstTranslator {
|
|||
|
||||
@Override
|
||||
protected TypeReference makeType(CAstType type) {
|
||||
Assertions.UNREACHABLE("JavaScript does not use CAstType");
|
||||
return null;
|
||||
assert "Any".equals(type.getName());
|
||||
return JavaScriptTypes.Root;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean ignoreName(String name) {
|
||||
return super.ignoreName(name) || name.endsWith(" temp");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] makeNameMap(CAstEntity n, Set<Scope> scopes, SSAInstruction[] insts) {
|
||||
String[] names = super.makeNameMap(n, scopes, insts);
|
||||
for(SSAInstruction inst : insts) {
|
||||
if (inst instanceof PrototypeLookup) {
|
||||
if (names[ inst.getUse(0)] != null) {
|
||||
names[ inst.getDef() ] = names[ inst.getUse(0) ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an instruction that checks if readVn is undefined and throws an exception if it isn't
|
||||
*/
|
||||
|
@ -96,16 +122,16 @@ public class JSAstTranslator extends AstTranslator {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected int doLexicallyScopedRead(CAstNode n, WalkContext context, String name) {
|
||||
int readVn = super.doLexicallyScopedRead(n, context, name);
|
||||
protected int doLexicallyScopedRead(CAstNode n, WalkContext context, String name, TypeReference type) {
|
||||
int readVn = super.doLexicallyScopedRead(n, context, name, type);
|
||||
// should get an exception if name is undefined
|
||||
addDefinedCheck(n, context, readVn);
|
||||
return readVn;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int doGlobalRead(CAstNode n, WalkContext context, String name) {
|
||||
int readVn = super.doGlobalRead(n, context, name);
|
||||
protected int doGlobalRead(CAstNode n, WalkContext context, String name, TypeReference type) {
|
||||
int readVn = super.doGlobalRead(n, context, name, type);
|
||||
// add a check if name is undefined, unless we're reading the value 'undefined'
|
||||
if (!("undefined".equals(name) || "$$undefined".equals(name))) {
|
||||
addDefinedCheck(n, context, readVn);
|
||||
|
@ -200,7 +226,7 @@ public class JSAstTranslator extends AstTranslator {
|
|||
protected void doMaterializeFunction(CAstNode n, WalkContext context, int result, int exception, CAstEntity fn) {
|
||||
int nm = context.currentScope().getConstantValue("L" + composeEntityName(context, fn));
|
||||
// "Function" is the name we use to model the constructor of function values
|
||||
int tmp = super.doGlobalRead(n, context, "Function");
|
||||
int tmp = super.doGlobalRead(n, context, "Function", JavaScriptTypes.Function);
|
||||
context.cfg().addInstruction(
|
||||
((JSInstructionFactory)insts).Invoke(context.cfg().getCurrentInstruction(), tmp, result, new int[]{ nm }, exception,
|
||||
new JSCallSiteReference(JavaScriptMethods.ctorReference, context.cfg().getCurrentInstruction())));
|
||||
|
@ -394,14 +420,13 @@ public class JSAstTranslator extends AstTranslator {
|
|||
|
||||
int tempVal = context.currentScope().allocateTempValue();
|
||||
doNewObject(context, null, tempVal, "Array", null);
|
||||
CAstSymbol args = new CAstSymbolImpl("arguments");
|
||||
CAstSymbol args = new CAstSymbolImpl("arguments", Any);
|
||||
context.currentScope().declare(args, tempVal);
|
||||
//context.cfg().addInstruction(((JSInstructionFactory)insts).PutInstruction(context.cfg().getCurrentInstruction(), 1, tempVal, "arguments"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doVisit(CAstNode n, WalkContext cntxt, CAstVisitor<WalkContext> visitor) {
|
||||
WalkContext context = (WalkContext) cntxt;
|
||||
protected boolean doVisit(CAstNode n, WalkContext context, CAstVisitor<WalkContext> visitor) {
|
||||
switch (n.getKind()) {
|
||||
case CAstNode.TYPE_OF: {
|
||||
int result = context.currentScope().allocateTempValue();
|
||||
|
@ -432,4 +457,27 @@ public class JSAstTranslator extends AstTranslator {
|
|||
}
|
||||
}
|
||||
|
||||
public static final CAstType Any = new CAstType() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Any";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection getSupertypes() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected CAstType topType() {
|
||||
return Any;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CAstType exceptionType() {
|
||||
return Any;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ public class PropertyReadExpander extends CAstRewriter<PropertyReadExpander.Rewr
|
|||
result = Ast.makeNode(
|
||||
CAstNode.BLOCK_EXPR,
|
||||
// declare loop variable and initialize to the receiver
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, false, false)), receiver),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, JSAstTranslator.Any, false, false)), receiver),
|
||||
Ast.makeNode(CAstNode.LOOP,
|
||||
// while the desired property of the loop variable is not
|
||||
// defined...
|
||||
|
@ -208,8 +208,8 @@ public class PropertyReadExpander extends CAstRewriter<PropertyReadExpander.Rewr
|
|||
CAstNode get;
|
||||
CAstNode result = Ast.makeNode(
|
||||
CAstNode.BLOCK_EXPR,
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, false, false)), receiver),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(elementTemp, false, false)), element),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(receiverTemp, JSAstTranslator.Any, false, false)), receiver),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(elementTemp, JSAstTranslator.Any, false, false)), element),
|
||||
Ast.makeNode(
|
||||
CAstNode.LOOP,
|
||||
Ast.makeNode(
|
||||
|
@ -260,11 +260,11 @@ public class PropertyReadExpander extends CAstRewriter<PropertyReadExpander.Rewr
|
|||
CAstNode copy = Ast.makeNode(
|
||||
CAstNode.BLOCK_EXPR,
|
||||
// assign lval to temp1 (where lval is a block that includes the prototype chain loop)
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp1, true, false)), lval),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp1, JSAstTranslator.Any, true, false)), lval),
|
||||
// ? --MS
|
||||
//rval,
|
||||
// assign temp2 the new value to be assigned
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp2, true, false)),
|
||||
Ast.makeNode(CAstNode.DECL_STMT, Ast.makeConstant(new InternalCAstSymbol(temp2, JSAstTranslator.Any, true, false)),
|
||||
Ast.makeNode(CAstNode.BINARY_EXPR, op, Ast.makeNode(CAstNode.VAR, Ast.makeConstant(temp1)), rval)),
|
||||
// write temp2 into the property
|
||||
Ast.makeNode(CAstNode.ASSIGN, Ast.makeNode(CAstNode.OBJECT_REF, ctxt.receiverTemp, ctxt.elementTemp),
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
package com.ibm.wala.cast.js.translator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
|
||||
import com.ibm.wala.cast.tree.CAstSourcePositionMap.Position;
|
||||
|
@ -78,7 +79,7 @@ public class RangePosition extends AbstractSourcePosition implements Position {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return url.openStream();
|
||||
public Reader getReader() throws IOException {
|
||||
return new InputStreamReader(url.openStream());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,20 @@ package com.ibm.wala.cast.js.util;
|
|||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cast.js.ssa.PrototypeLookup;
|
||||
import com.ibm.wala.cast.loader.CAstAbstractLoader;
|
||||
import com.ibm.wala.classLoader.IClassLoader;
|
||||
import com.ibm.wala.classLoader.ModuleEntry;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetAction;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
import com.ibm.wala.util.intset.MutableIntSet;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
|
||||
public class Util {
|
||||
|
@ -47,6 +56,49 @@ public class Util {
|
|||
throw new WalaException(String.valueOf(message));
|
||||
}
|
||||
}
|
||||
|
||||
public static IntSet getArgumentsArrayVns(IR ir, final DefUse du) {
|
||||
int originalArgsVn = getArgumentsArrayVn(ir);
|
||||
final MutableIntSet result = IntSetUtil.make();
|
||||
if (originalArgsVn == -1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.add(originalArgsVn);
|
||||
int size;
|
||||
do {
|
||||
size = result.size();
|
||||
result.foreach(new IntSetAction() {
|
||||
@Override
|
||||
public void act(int vn) {
|
||||
for(Iterator<SSAInstruction> insts = du.getUses(vn); insts.hasNext(); ) {
|
||||
SSAInstruction inst = insts.next();
|
||||
if (inst instanceof PrototypeLookup || inst instanceof SSAPhiInstruction) {
|
||||
result.add(inst.getDef());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} while (size != result.size());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int getArgumentsArrayVn(IR ir) {
|
||||
for(int i = 0; i < ir.getInstructions().length; i++) {
|
||||
SSAInstruction inst = ir.getInstructions()[i];
|
||||
if (inst != null) {
|
||||
for(int v = 0; v < inst.getNumberOfUses(); v++) {
|
||||
String[] names = ir.getLocalNames(i, inst.getUse(v));
|
||||
if (names != null && names.length == 1 && "arguments".equals(names[0])) {
|
||||
return inst.getUse(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public class AstCallGraph extends ExplicitCallGraph {
|
|||
}
|
||||
|
||||
public AstLexicalRead addGlobalRead(TypeReference type, String name) {
|
||||
AstLexicalRead s = new AstLexicalRead(statements.size(), nextLocal++, null, name);
|
||||
AstLexicalRead s = new AstLexicalRead(statements.size(), nextLocal++, null, name, type);
|
||||
statements.add(s);
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -425,7 +423,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
||||
@Override
|
||||
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
||||
final IntSetVariable objects = (IntSetVariable) rhs;
|
||||
final IntSetVariable objects = rhs;
|
||||
if (objects.getValue() != null) {
|
||||
objects.getValue().foreach(new IntSetAction() {
|
||||
@Override
|
||||
|
@ -491,7 +489,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
||||
@Override
|
||||
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
||||
final IntSetVariable objects = (IntSetVariable) rhs;
|
||||
final IntSetVariable objects = rhs;
|
||||
if (objects.getValue() != null) {
|
||||
objects.getValue().foreach(new IntSetAction() {
|
||||
@Override
|
||||
|
@ -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
|
||||
|
@ -950,8 +911,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
|
||||
|
@ -1011,7 +972,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
||||
@Override
|
||||
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
||||
final IntSetVariable objects = (IntSetVariable) rhs;
|
||||
final IntSetVariable objects = rhs;
|
||||
if (objects.getValue() != null) {
|
||||
objects.getValue().foreach(new IntSetAction() {
|
||||
@Override
|
||||
|
@ -1075,7 +1036,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
system.newSideEffect(new UnaryOperator<PointsToSetVariable>() {
|
||||
@Override
|
||||
public byte evaluate(PointsToSetVariable lhs, PointsToSetVariable rhs) {
|
||||
final IntSetVariable fields = (IntSetVariable) rhs;
|
||||
final IntSetVariable fields = rhs;
|
||||
if (fields.getValue() != null) {
|
||||
fields.getValue().foreach(new IntSetAction() {
|
||||
@Override
|
||||
|
|
|
@ -11,7 +11,6 @@ package com.ibm.wala.cast.ipa.callgraph;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
|
@ -19,7 +18,6 @@ import com.ibm.wala.cast.loader.SingleClassLoaderFactory;
|
|||
import com.ibm.wala.classLoader.ArrayClassLoader;
|
||||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.classLoader.SourceModule;
|
||||
import com.ibm.wala.classLoader.SourceURLModule;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
@ -42,13 +40,6 @@ public class CAstAnalysisScope extends AnalysisScope {
|
|||
}
|
||||
}
|
||||
|
||||
public CAstAnalysisScope(URL[] sources, SingleClassLoaderFactory loaders, Collection<Language> languages) throws IOException {
|
||||
this(loaders, languages);
|
||||
for (int i = 0; i < sources.length; i++) {
|
||||
addToScope(theLoader, new SourceURLModule(sources[i]));
|
||||
}
|
||||
}
|
||||
|
||||
public CAstAnalysisScope(SourceModule[] sources, SingleClassLoaderFactory loaders, Collection<Language> languages)
|
||||
throws IOException {
|
||||
this(loaders, languages);
|
||||
|
|
|
@ -68,11 +68,6 @@ public class CAstCallGraphUtil {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static AnalysisScope makeScope(URL[] files, SingleClassLoaderFactory loaders, Language language) throws IOException {
|
||||
CAstAnalysisScope result = new CAstAnalysisScope(files, loaders, Collections.singleton(language));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static AnalysisCache makeCache(IRFactory<IMethod> factory) {
|
||||
return new AnalysisCache(factory);
|
||||
}
|
||||
|
|
|
@ -103,8 +103,7 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory {
|
|||
result = new CompoundIterator<CGNode>(result, new NonNullSingletonIterator<CGNode>(callerOfConstructor));
|
||||
} else {
|
||||
PointerKey funcKey = builder.getPointerKeyForLocal(callerOfConstructor, 1);
|
||||
OrdinalSet<InstanceKey> funcPtrs = builder.getPointerAnalysis().getPointsToSet(funcKey);
|
||||
for (InstanceKey funcPtr : funcPtrs) {
|
||||
for (InstanceKey funcPtr : builder.getPointerAnalysis().getPointsToSet(funcKey)) {
|
||||
if (funcPtr instanceof ScopeMappingInstanceKey) {
|
||||
result = new CompoundIterator<CGNode>(result, ((ScopeMappingInstanceKey) funcPtr).getFunargNodes(name));
|
||||
}
|
||||
|
|
|
@ -103,4 +103,16 @@ public abstract class ScriptEntryPoints implements Iterable<Entrypoint> {
|
|||
return ES.iterator();
|
||||
}
|
||||
|
||||
}
|
||||
public Entrypoint make(String scriptName) {
|
||||
IClass cls = cha.lookupClass(TypeReference.findOrCreate(scriptType.getClassLoader().getReference(), scriptName));
|
||||
assert cls != null && cha.isSubclassOf(cls, scriptType) && !cls.isAbstract() : String.valueOf(cls) + " for " + scriptName;
|
||||
for (IMethod method : cls.getDeclaredMethods()) {
|
||||
if (keep(method)) {
|
||||
return new ScriptEntryPoint(method);
|
||||
}
|
||||
}
|
||||
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ public class CrossLanguageClassHierarchy implements IClassHierarchy {
|
|||
}
|
||||
|
||||
private IClassHierarchy getHierarchy(Atom language) {
|
||||
return (IClassHierarchy) hierarchies.get(language);
|
||||
return hierarchies.get(language);
|
||||
}
|
||||
|
||||
private IClassHierarchy getHierarchy(IClassLoader loader) {
|
||||
|
@ -105,7 +105,7 @@ public class CrossLanguageClassHierarchy implements IClassHierarchy {
|
|||
loaders.add(getLoader((ClassLoaderReference) ldrs.next()));
|
||||
}
|
||||
|
||||
return (IClassLoader[]) loaders.toArray(new IClassLoader[loaders.size()]);
|
||||
return loaders.toArray(new IClassLoader[loaders.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -121,7 +121,7 @@ public class LexicalModRef {
|
|||
Collection<Pair<CGNode, String>> result = HashSetFactory.make();
|
||||
// use scope-mapping instance keys in pointer analysis. may need a different
|
||||
// scheme for CG construction not based on pointer analysis
|
||||
OrdinalSet<InstanceKey> functionValues = pa.getPointsToSet(pa.getHeapModel().getPointerKeyForLocal(n, 1));
|
||||
OrdinalSet<? extends InstanceKey> functionValues = pa.getPointsToSet(pa.getHeapModel().getPointerKeyForLocal(n, 1));
|
||||
for (InstanceKey ik : functionValues) {
|
||||
if (ik instanceof ScopeMappingInstanceKey) {
|
||||
ScopeMappingInstanceKey smik = (ScopeMappingInstanceKey) ik;
|
||||
|
|
|
@ -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 iindex, int results[], int exception, CallSiteReference site) {
|
||||
super(iindex, results, exception, site);
|
||||
}
|
||||
|
||||
protected AbstractLexicalInvoke(int iindex, int result, int exception, CallSiteReference site) {
|
||||
this(iindex, new int[] { result }, exception, site);
|
||||
}
|
||||
|
||||
protected AbstractLexicalInvoke(int iindex, int results[], int exception, CallSiteReference site, Access[] lexicalReads,
|
||||
Access[] lexicalWrites) {
|
||||
this(iindex, 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();
|
||||
}
|
||||
}
|
|
@ -261,7 +261,7 @@ public abstract class AbstractSSAConversion {
|
|||
|
||||
initializeVariables();
|
||||
|
||||
SEARCH((SSACFG.BasicBlock) CFG.entry());
|
||||
SEARCH(CFG.entry());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
|
|||
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.types.FieldReference;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
||||
public interface AstInstructionFactory extends SSAInstructionFactory {
|
||||
|
||||
|
@ -38,13 +39,13 @@ public interface AstInstructionFactory extends SSAInstructionFactory {
|
|||
|
||||
AstLexicalRead LexicalRead(int iindex, Access access);
|
||||
|
||||
AstLexicalRead LexicalRead(int iindex, int lhs, String definer, String globalName);
|
||||
AstLexicalRead LexicalRead(int iindex, int lhs, String definer, String globalName, TypeReference type);
|
||||
|
||||
AstLexicalWrite LexicalWrite(int iindex, Access[] accesses);
|
||||
|
||||
AstLexicalWrite LexicalWrite(int iindex, Access access);
|
||||
|
||||
AstLexicalWrite LexicalWrite(int iindex, String definer, String globalName, int rhs);
|
||||
AstLexicalWrite LexicalWrite(int iindex, String definer, String globalName, TypeReference type, int rhs);
|
||||
|
||||
EachElementGetInstruction EachElementGetInstruction(int iindex, int lValue, int objectRef);
|
||||
|
||||
|
|
|
@ -39,14 +39,19 @@ public abstract class AstLexicalAccess extends SSAInstruction {
|
|||
* name of entity that defines the variable
|
||||
*/
|
||||
public final String variableDefiner;
|
||||
/**
|
||||
* type of the lexical value
|
||||
*/
|
||||
public final TypeReference type;
|
||||
/**
|
||||
* value number used for name where access is being performed (not in the declaring entity)
|
||||
*/
|
||||
public final int valueNumber;
|
||||
|
||||
public Access(String name, String definer, int vn) {
|
||||
public Access(String name, String definer, TypeReference type, int vn) {
|
||||
variableName = name;
|
||||
variableDefiner = definer;
|
||||
this.type = type;
|
||||
valueNumber = vn;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
||||
/**
|
||||
* A set of lexical reads. This instruction represents reads of a set of variables that are defined by a pair of
|
||||
|
@ -32,8 +33,8 @@ public class AstLexicalRead extends AstLexicalAccess {
|
|||
this(iindex, new Access[] { access });
|
||||
}
|
||||
|
||||
public AstLexicalRead(int iindex, int lhs, String definer, String globalName) {
|
||||
this(iindex, new Access(globalName, definer, lhs));
|
||||
public AstLexicalRead(int iindex, int lhs, String definer, String globalName, TypeReference type) {
|
||||
this(iindex, new Access(globalName, definer, type, lhs));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,7 +45,7 @@ public class AstLexicalRead extends AstLexicalAccess {
|
|||
Access[] accesses = new Access[getAccessCount()];
|
||||
for (int i = 0; i < accesses.length; i++) {
|
||||
Access oldAccess = getAccess(i);
|
||||
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, defs[i]);
|
||||
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, oldAccess.type, defs[i]);
|
||||
}
|
||||
|
||||
return ((AstInstructionFactory)insts).LexicalRead(iindex, accesses);
|
||||
|
|
|
@ -13,6 +13,7 @@ package com.ibm.wala.cast.ir.ssa;
|
|||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
|
||||
/**
|
||||
* A set of lexical writes. This instruction represents writes of a set of variables that are defined by a pair of
|
||||
|
@ -24,8 +25,8 @@ import com.ibm.wala.ssa.SymbolTable;
|
|||
*/
|
||||
public class AstLexicalWrite extends AstLexicalAccess {
|
||||
|
||||
public AstLexicalWrite(int iindex, String definer, String globalName, int rhs) {
|
||||
this(iindex, new Access(globalName, definer, rhs));
|
||||
public AstLexicalWrite(int iindex, String definer, String globalName, TypeReference type, int rhs) {
|
||||
this(iindex, new Access(globalName, definer, type, rhs));
|
||||
}
|
||||
|
||||
public AstLexicalWrite(int iindex, Access access) {
|
||||
|
@ -44,7 +45,7 @@ public class AstLexicalWrite extends AstLexicalAccess {
|
|||
Access[] accesses = new Access[getAccessCount()];
|
||||
for (int i = 0; i < accesses.length; i++) {
|
||||
Access oldAccess = getAccess(i);
|
||||
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, uses[i]);
|
||||
accesses[i] = new Access(oldAccess.variableName, oldAccess.variableDefiner, oldAccess.type, uses[i]);
|
||||
}
|
||||
|
||||
return ((AstInstructionFactory)insts).LexicalWrite(iindex, accesses);
|
||||
|
|
|
@ -10,21 +10,21 @@
|
|||
*****************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* This abstract instruction extends the abstract lexical invoke with
|
||||
* This abstract instruction extends the abstract invoke with
|
||||
* functionality to support invocations with a fixed number of
|
||||
* arguments---the only case in some languages and a common case even
|
||||
* in scripting languages.
|
||||
*
|
||||
*
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*/
|
||||
public abstract class FixedParametersLexicalInvokeInstruction
|
||||
extends AbstractLexicalInvoke
|
||||
public abstract class FixedParametersInvokeInstruction
|
||||
extends MultiReturnValueInvokeInstruction
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -34,12 +34,12 @@ public abstract class FixedParametersLexicalInvokeInstruction
|
|||
*/
|
||||
private final int[] params;
|
||||
|
||||
public FixedParametersLexicalInvokeInstruction(int iindex, int results[], int[] params, int exception, CallSiteReference site) {
|
||||
public FixedParametersInvokeInstruction(int iindex, int results[], int[] params, int exception, CallSiteReference site) {
|
||||
super(iindex, results, exception, site);
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public FixedParametersLexicalInvokeInstruction(int iindex, int result, int[] params, int exception, CallSiteReference site) {
|
||||
public FixedParametersInvokeInstruction(int iindex, int result, int[] params, int exception, CallSiteReference site) {
|
||||
this(iindex, new int[]{result}, params, exception, site);
|
||||
}
|
||||
|
||||
|
@ -48,61 +48,43 @@ public abstract class FixedParametersLexicalInvokeInstruction
|
|||
* @param i
|
||||
* @param params
|
||||
*/
|
||||
public FixedParametersLexicalInvokeInstruction(int iindex, int[] params, int exception, CallSiteReference site) {
|
||||
public FixedParametersInvokeInstruction(int iindex, int[] params, int exception, CallSiteReference site) {
|
||||
this(iindex, null, params, exception, site);
|
||||
}
|
||||
|
||||
protected FixedParametersLexicalInvokeInstruction(int iindex, int results[], int[] params, int exception, CallSiteReference site, Access[] lexicalReads, Access[] lexicalWrites) {
|
||||
super(iindex, 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 +96,26 @@ public abstract class FixedParametersLexicalInvokeInstruction
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see com.ibm.wala.ssa.Instruction#getUse(int)
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void visit(IVisitor v) {
|
||||
// TODO Auto-generated method stub
|
||||
assert false;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfUses() {
|
||||
return getNumberOfParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// TODO Auto-generated method stub
|
||||
assert false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUse(int j) {
|
||||
if (j < getNumberOfParameters())
|
|
@ -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[];
|
||||
|
|
|
@ -206,7 +206,7 @@ public class SSAConversion extends AbstractSSAConversion {
|
|||
PhiUseRecord use = (PhiUseRecord) x;
|
||||
int bb = use.BBnumber;
|
||||
int phi = use.phiNumber;
|
||||
SSACFG.BasicBlock BB = (SSACFG.BasicBlock) CFG.getNode(bb);
|
||||
SSACFG.BasicBlock BB = CFG.getNode(bb);
|
||||
BB.addPhiForLocal(phi, (SSAPhiInstruction) undo(BB.getPhiForLocal(phi), use.useNumber, lhs));
|
||||
copyPropagationMap.remove(use);
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ public class SSAConversion extends AbstractSSAConversion {
|
|||
|
||||
private CopyPropagationRecord topR(int v) {
|
||||
if (R[v] != null && !R[v].isEmpty()) {
|
||||
CopyPropagationRecord rec = (CopyPropagationRecord) R[v].peek();
|
||||
CopyPropagationRecord rec = R[v].peek();
|
||||
if (top(v) == rec.rhs) {
|
||||
return rec;
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ public class SSAConversion extends AbstractSSAConversion {
|
|||
this.R = new Stack[ir.getSymbolTable().getMaxValueNumber() + 1];
|
||||
|
||||
for (int i = 0; i < CFG.getNumberOfNodes(); i++) {
|
||||
SSACFG.BasicBlock bb = (SSACFG.BasicBlock) CFG.getNode(i);
|
||||
SSACFG.BasicBlock bb = CFG.getNode(i);
|
||||
if (bb.hasPhi()) {
|
||||
int n = 0;
|
||||
for (Iterator X = bb.iteratePhis(); X.hasNext(); n++)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue