delete CallGraph.getInterpreter() and CFGProvider
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1346 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
e34aa83beb
commit
2445a55ad8
|
@ -10,31 +10,54 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.ipa.callgraph;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.cast.js.ipa.summaries.*;
|
||||
import com.ibm.wala.cast.js.loader.*;
|
||||
import com.ibm.wala.cast.js.ssa.*;
|
||||
import com.ibm.wala.cast.js.types.*;
|
||||
import com.ibm.wala.cast.types.*;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.ipa.callgraph.*;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
||||
import com.ibm.wala.cast.js.ipa.summaries.JavaScriptSummarizedFunction;
|
||||
import com.ibm.wala.cast.js.ipa.summaries.JavaScriptSummary;
|
||||
import com.ibm.wala.cast.js.loader.JSCallSiteReference;
|
||||
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptNewInstruction;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyRead;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptStaticPropertyRead;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptStaticPropertyWrite;
|
||||
import com.ibm.wala.cast.js.types.JavaScriptMethods;
|
||||
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;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.SourceFileModule;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ipa.summaries.MethodSummary;
|
||||
import com.ibm.wala.ssa.*;
|
||||
import com.ibm.wala.types.*;
|
||||
import com.ibm.wala.ssa.ConstantValue;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstructionFactory;
|
||||
import com.ibm.wala.ssa.SymbolTable;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
||||
public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private final IClassHierarchy cha;
|
||||
|
||||
private final MethodTargetSelector base;
|
||||
|
||||
private final WarningSet warnings;
|
||||
|
||||
private final Map<Object, IMethod> constructors = new HashMap<Object, IMethod>();
|
||||
|
@ -42,19 +65,12 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
private class JavaScriptConstructor extends JavaScriptSummarizedFunction {
|
||||
private final String toStringExtra;
|
||||
|
||||
private JavaScriptConstructor(MethodReference ref,
|
||||
MethodSummary summary,
|
||||
IClass declaringClass,
|
||||
String toStringExtra)
|
||||
{
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass, String toStringExtra) {
|
||||
super(ref, summary, declaringClass);
|
||||
this.toStringExtra = toStringExtra;
|
||||
}
|
||||
|
||||
private JavaScriptConstructor(MethodReference ref,
|
||||
MethodSummary summary,
|
||||
IClass declaringClass)
|
||||
{
|
||||
private JavaScriptConstructor(MethodReference ref, MethodSummary summary, IClass declaringClass) {
|
||||
this(ref, summary, declaringClass, "");
|
||||
}
|
||||
|
||||
|
@ -63,33 +79,24 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
}
|
||||
|
||||
public JavaScriptConstructTargetSelector(IClassHierarchy cha,
|
||||
MethodTargetSelector base,
|
||||
WarningSet warnings)
|
||||
{
|
||||
public JavaScriptConstructTargetSelector(IClassHierarchy cha, MethodTargetSelector base, WarningSet warnings) {
|
||||
this.cha = cha;
|
||||
this.base = base;
|
||||
this.warnings = warnings;
|
||||
}
|
||||
|
||||
|
||||
private IMethod record(Object key, IMethod m) {
|
||||
constructors.put(key, m);
|
||||
return m;
|
||||
}
|
||||
|
||||
private IMethod makeNullaryValueConstructor(IClass cls, Object value) {
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( cls.getReference() );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(cls.getReference());
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(4, 1, "prototype"));
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
5,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
cls.getReference())));
|
||||
S.addStatement(new JavaScriptNewInstruction(5, NewSiteReference.make(S.getNextProgramCounter(), cls.getReference())));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(5, "prototype", 4));
|
||||
|
||||
|
@ -102,18 +109,12 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
|
||||
private IMethod makeUnaryValueConstructor(IClass cls) {
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( cls.getReference() );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(cls.getReference());
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(5, 1, "prototype"));
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
6,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
cls.getReference())));
|
||||
S.addStatement(new JavaScriptNewInstruction(6, NewSiteReference.make(S.getNextProgramCounter(), cls.getReference())));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(6, "prototype", 5));
|
||||
|
||||
|
@ -128,29 +129,20 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
Assertions._assert(nargs == 0 || nargs == 1);
|
||||
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
else return
|
||||
record(
|
||||
key,
|
||||
(nargs==0)?
|
||||
makeNullaryValueConstructor(cls, value):
|
||||
makeUnaryValueConstructor(cls));
|
||||
else
|
||||
return record(key, (nargs == 0) ? makeNullaryValueConstructor(cls, value) : makeUnaryValueConstructor(cls));
|
||||
}
|
||||
|
||||
private IMethod makeNullaryObjectConstructor(IClass cls) {
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( JavaScriptTypes.Object );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Object);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(4, 1, "prototype"));
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
5,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Object)));
|
||||
S.addStatement(new JavaScriptNewInstruction(5, NewSiteReference.make(S.getNextProgramCounter(), JavaScriptTypes.Object)));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(5, "prototype", 4));
|
||||
|
||||
|
@ -160,10 +152,9 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
|
||||
private IMethod makeUnaryObjectConstructor(IClass cls) {
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( JavaScriptTypes.Object );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Object);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(2, false));
|
||||
|
||||
return new JavaScriptConstructor(ref, S, cls);
|
||||
|
@ -173,41 +164,31 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
Assertions._assert(nargs == 0 || nargs == 1);
|
||||
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
else return
|
||||
record(
|
||||
key,
|
||||
(nargs==0)?
|
||||
makeNullaryObjectConstructor(cls):
|
||||
makeUnaryObjectConstructor(cls));
|
||||
else
|
||||
return record(key, (nargs == 0) ? makeNullaryObjectConstructor(cls) : makeUnaryObjectConstructor(cls));
|
||||
}
|
||||
|
||||
private IMethod makeObjectCall(IClass cls, int nargs) {
|
||||
Assertions._assert(nargs == 0);
|
||||
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
else return
|
||||
record(
|
||||
key,
|
||||
makeNullaryObjectConstructor(cls));
|
||||
else
|
||||
return record(key, makeNullaryObjectConstructor(cls));
|
||||
}
|
||||
|
||||
private IMethod makeArrayLengthConstructor(IClass cls) {
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( JavaScriptTypes.Array );
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Array);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(5, 1, "prototype"));
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
6,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Array)));
|
||||
S.addStatement(new JavaScriptNewInstruction(6, NewSiteReference.make(S.getNextProgramCounter(), JavaScriptTypes.Array)));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(6, "prototype", 5));
|
||||
|
||||
|
@ -219,29 +200,25 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
|
||||
private IMethod makeArrayContentsConstructor(IClass cls, int nargs) {
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( JavaScriptTypes.Array );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, nargs+1);
|
||||
|
||||
S.addConstant(new Integer(nargs+3), new ConstantValue("prototype"));
|
||||
S.addStatement(new JavaScriptPropertyRead(nargs+4, 1, nargs+3));
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Array);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, nargs + 1);
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
nargs+5,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Array)));
|
||||
S.addConstant(new Integer(nargs + 3), new ConstantValue("prototype"));
|
||||
S.addStatement(new JavaScriptPropertyRead(nargs + 4, 1, nargs + 3));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(nargs+5, "prototype", nargs+4));
|
||||
S
|
||||
.addStatement(new JavaScriptNewInstruction(nargs + 5, NewSiteReference.make(S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Array)));
|
||||
|
||||
S.addConstant(new Integer(nargs+7), new ConstantValue(nargs));
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(nargs+5, "length", nargs+7));
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(nargs + 5, "prototype", nargs + 4));
|
||||
|
||||
int vn = nargs+9;
|
||||
for(int i = 0; i < nargs; i++, vn+=2) {
|
||||
S.addConstant(new Integer(nargs + 7), new ConstantValue(nargs));
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(nargs + 5, "length", nargs + 7));
|
||||
|
||||
int vn = nargs + 9;
|
||||
for (int i = 0; i < nargs; i++, vn += 2) {
|
||||
S.addConstant(new Integer(vn), new ConstantValue(i));
|
||||
S.addStatement(new JavaScriptPropertyWrite(nargs+5, vn, i+1));
|
||||
S.addStatement(new JavaScriptPropertyWrite(nargs + 5, vn, i + 1));
|
||||
}
|
||||
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(5, false));
|
||||
|
@ -251,20 +228,16 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
private IMethod makeArrayConstructor(IClass cls, int nargs) {
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
else return
|
||||
record(
|
||||
key,
|
||||
(nargs==1)?
|
||||
makeArrayLengthConstructor(cls):
|
||||
makeArrayContentsConstructor(cls, nargs));
|
||||
else
|
||||
return record(key, (nargs == 1) ? makeArrayLengthConstructor(cls) : makeArrayContentsConstructor(cls, nargs));
|
||||
}
|
||||
|
||||
private IMethod makeNullaryStringCall(IClass cls) {
|
||||
MethodReference ref =
|
||||
AstMethodReference.fnReference( JavaScriptTypes.String );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.String);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
|
||||
S.addConstant(new Integer(2), new ConstantValue(""));
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(2, false));
|
||||
|
@ -273,14 +246,13 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
|
||||
private IMethod makeUnaryStringCall(IClass cls) {
|
||||
MethodReference ref =
|
||||
AstMethodReference.fnReference( JavaScriptTypes.String );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.String);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(4, 2, "toString"));
|
||||
|
||||
CallSiteReference cs = new JSCallSiteReference(S.getNextProgramCounter());
|
||||
S.addStatement(new JavaScriptInvoke(4, 5, new int[]{2}, 6, cs));
|
||||
S.addStatement(new JavaScriptInvoke(4, 5, new int[] { 2 }, 6, cs));
|
||||
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(5, false));
|
||||
|
||||
|
@ -291,20 +263,16 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
Assertions._assert(nargs == 0 || nargs == 1);
|
||||
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
else return
|
||||
record(
|
||||
key,
|
||||
(nargs==0)?
|
||||
makeNullaryStringCall(cls):
|
||||
makeUnaryStringCall(cls));
|
||||
else
|
||||
return record(key, (nargs == 0) ? makeNullaryStringCall(cls) : makeUnaryStringCall(cls));
|
||||
}
|
||||
|
||||
|
||||
private IMethod makeNullaryNumberCall(IClass cls) {
|
||||
MethodReference ref =
|
||||
AstMethodReference.fnReference( JavaScriptTypes.Number );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.Number);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
|
||||
S.addConstant(new Integer(2), new ConstantValue(0.0));
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(2, false));
|
||||
|
@ -313,14 +281,13 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
|
||||
private IMethod makeUnaryNumberCall(IClass cls) {
|
||||
MethodReference ref =
|
||||
AstMethodReference.fnReference( JavaScriptTypes.Number );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.Number);
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(4, 2, "toNumber"));
|
||||
|
||||
CallSiteReference cs = new JSCallSiteReference(S.getNextProgramCounter());
|
||||
S.addStatement(new JavaScriptInvoke(4, 5, new int[]{2}, 6, cs));
|
||||
S.addStatement(new JavaScriptInvoke(4, 5, new int[] { 2 }, 6, cs));
|
||||
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(5, false));
|
||||
|
||||
|
@ -331,41 +298,28 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
Assertions._assert(nargs == 0 || nargs == 1);
|
||||
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
else return
|
||||
record(
|
||||
key,
|
||||
(nargs==0)?
|
||||
makeNullaryNumberCall(cls):
|
||||
makeUnaryNumberCall(cls));
|
||||
else
|
||||
return record(key, (nargs == 0) ? makeNullaryNumberCall(cls) : makeUnaryNumberCall(cls));
|
||||
}
|
||||
|
||||
private IMethod makeFunctionConstructor(IClass receiver, IClass cls) {
|
||||
Pair<IClass,IClass> tableKey = new Pair<IClass,IClass>(receiver, cls);
|
||||
if (constructors.containsKey(tableKey)) return constructors.get(tableKey);
|
||||
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( receiver.getReference() );
|
||||
private IMethod makeFunctionConstructor(IClass receiver, IClass cls) {
|
||||
Pair<IClass, IClass> tableKey = new Pair<IClass, IClass>(receiver, cls);
|
||||
if (constructors.containsKey(tableKey))
|
||||
return constructors.get(tableKey);
|
||||
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(receiver.getReference());
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
|
||||
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(4, 1, "prototype"));
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
5,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
cls.getReference())));
|
||||
S.addStatement(new JavaScriptNewInstruction(5, NewSiteReference.make(S.getNextProgramCounter(), cls.getReference())));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(5, "prototype", 4));
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
7,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Object)));
|
||||
S.addStatement(new JavaScriptNewInstruction(7, NewSiteReference.make(S.getNextProgramCounter(), JavaScriptTypes.Object)));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(5, "prototype", 7));
|
||||
|
||||
|
@ -374,7 +328,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
S.addStatement(SSAInstructionFactory.ReturnInstruction(5, false));
|
||||
|
||||
if (receiver != cls)
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver, "("+cls.getReference().getName()+")"));
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver, "(" + cls.getReference().getName() + ")"));
|
||||
else
|
||||
return record(tableKey, new JavaScriptConstructor(ref, S, receiver));
|
||||
}
|
||||
|
@ -383,104 +337,99 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
|
||||
private IMethod makeFunctionConstructor(IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass cls, int nargs) {
|
||||
SymbolTable ST = callerIR.getSymbolTable();
|
||||
|
||||
|
||||
if (nargs == 0) {
|
||||
return makeFunctionConstructor(cls, cls);
|
||||
} else if (nargs==1) {
|
||||
} else if (nargs == 1) {
|
||||
if (ST.isStringConstant(callStmt.getUse(1))) {
|
||||
TypeReference ref =
|
||||
TypeReference.findOrCreate(
|
||||
JavaScriptTypes.jsLoader,
|
||||
TypeName.string2TypeName(
|
||||
(String)ST.getStringValue(callStmt.getUse(1)) ));
|
||||
TypeReference ref = TypeReference.findOrCreate(JavaScriptTypes.jsLoader, TypeName.string2TypeName((String) ST
|
||||
.getStringValue(callStmt.getUse(1))));
|
||||
|
||||
if (DEBUG) {
|
||||
Trace.println("ctor type name is " + (String)ST.getStringValue(callStmt.getUse(1)));
|
||||
}
|
||||
if (DEBUG) {
|
||||
Trace.println("ctor type name is " + (String) ST.getStringValue(callStmt.getUse(1)));
|
||||
}
|
||||
|
||||
IClass cls2 = cha.lookupClass( ref );
|
||||
if (cls2 != null) {
|
||||
return makeFunctionConstructor(cls, cls2);
|
||||
}
|
||||
IClass cls2 = cha.lookupClass(ref);
|
||||
if (cls2 != null) {
|
||||
return makeFunctionConstructor(cls, cls2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return makeFunctionConstructor(cls, cls);
|
||||
} else {
|
||||
Assertions._assert(nargs > 1);
|
||||
JavaScriptLoader cl = (JavaScriptLoader)
|
||||
cha.getLoader(JavaScriptTypes.jsLoader);
|
||||
JavaScriptLoader cl = (JavaScriptLoader) cha.getLoader(JavaScriptTypes.jsLoader);
|
||||
|
||||
for(int i = 1; i < callStmt.getNumberOfUses(); i++)
|
||||
if (! ST.isStringConstant(callStmt.getUse(i)))
|
||||
return makeFunctionConstructor(cls, cls);
|
||||
for (int i = 1; i < callStmt.getNumberOfUses(); i++)
|
||||
if (!ST.isStringConstant(callStmt.getUse(i)))
|
||||
return makeFunctionConstructor(cls, cls);
|
||||
|
||||
StringBuffer fun = new StringBuffer("function _fromctor (");
|
||||
for(int j = 1; j < callStmt.getNumberOfUses()-1; j++) {
|
||||
if (j != 1) fun.append(",");
|
||||
fun.append( ST.getStringValue(callStmt.getUse(j)) );
|
||||
for (int j = 1; j < callStmt.getNumberOfUses() - 1; j++) {
|
||||
if (j != 1)
|
||||
fun.append(",");
|
||||
fun.append(ST.getStringValue(callStmt.getUse(j)));
|
||||
}
|
||||
|
||||
|
||||
fun.append(") {");
|
||||
fun.append(ST.getStringValue(callStmt.getUse(callStmt.getNumberOfUses()-1)));
|
||||
fun.append(ST.getStringValue(callStmt.getUse(callStmt.getNumberOfUses() - 1)));
|
||||
fun.append("}");
|
||||
|
||||
try {
|
||||
String fileName = "ctor " + ++ctorCount;
|
||||
File f = new File(System.getProperty("java.io.tmpdir")+File.separator+fileName);
|
||||
FileWriter FO = new FileWriter(f);
|
||||
FO.write( fun.toString() );
|
||||
FO.close();
|
||||
(Util.getTranslatorFactory().make(cl)).translate(new SourceFileModule(f, System.getProperty("java.io.tmpdir")), fileName);
|
||||
f.delete();
|
||||
IClass fcls = cl.lookupClass("Lctor " + ctorCount + "/_fromctor", cha);
|
||||
cha.addClass( fcls );
|
||||
try {
|
||||
String fileName = "ctor " + ++ctorCount;
|
||||
File f = new File(System.getProperty("java.io.tmpdir") + File.separator + fileName);
|
||||
FileWriter FO = new FileWriter(f);
|
||||
FO.write(fun.toString());
|
||||
FO.close();
|
||||
(Util.getTranslatorFactory().make(cl)).translate(new SourceFileModule(f, System.getProperty("java.io.tmpdir")), fileName);
|
||||
f.delete();
|
||||
IClass fcls = cl.lookupClass("Lctor " + ctorCount + "/_fromctor", cha);
|
||||
cha.addClass(fcls);
|
||||
|
||||
if (DEBUG)
|
||||
Trace.println("looking for ctor " + ctorCount + " and got " + fcls);
|
||||
if (DEBUG)
|
||||
Trace.println("looking for ctor " + ctorCount + " and got " + fcls);
|
||||
|
||||
if (fcls != null)
|
||||
return makeFunctionConstructor(cls, fcls);
|
||||
|
||||
if (fcls != null)
|
||||
return makeFunctionConstructor(cls, fcls);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return makeFunctionConstructor(cls, cls);
|
||||
}
|
||||
}
|
||||
|
||||
private IMethod makeFunctionObjectConstructor(IClass cls, int nargs) {
|
||||
Object key = new Pair<IClass, Integer>(cls, new Integer(nargs));
|
||||
if (constructors.containsKey(key)) return constructors.get(key);
|
||||
if (constructors.containsKey(key))
|
||||
return constructors.get(key);
|
||||
|
||||
MethodReference ref =
|
||||
JavaScriptMethods.makeCtorReference( cls.getReference() );
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, nargs+1);
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(nargs+4, 1, "prototype"));
|
||||
MethodReference ref = JavaScriptMethods.makeCtorReference(cls.getReference());
|
||||
JavaScriptSummary S = new JavaScriptSummary(ref, nargs + 1);
|
||||
|
||||
S.addStatement(
|
||||
new JavaScriptNewInstruction(
|
||||
nargs+5,
|
||||
NewSiteReference.make(
|
||||
S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Object)));
|
||||
S.addStatement(new JavaScriptStaticPropertyRead(nargs + 4, 1, "prototype"));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(nargs+5, "prototype", nargs+4));
|
||||
S
|
||||
.addStatement(new JavaScriptNewInstruction(nargs + 5, NewSiteReference.make(S.getNextProgramCounter(),
|
||||
JavaScriptTypes.Object)));
|
||||
|
||||
S.addStatement(new JavaScriptStaticPropertyWrite(nargs + 5, "prototype", nargs + 4));
|
||||
|
||||
CallSiteReference cs = new JSCallSiteReference(S.getNextProgramCounter());
|
||||
int[] args = new int[ nargs+1 ];
|
||||
args[0] = nargs+5;
|
||||
for(int i = 0; i < nargs; i++) args[i+1] = i+2;
|
||||
S.addStatement(new JavaScriptInvoke(1, nargs+7, args, nargs+8, cs));
|
||||
int[] args = new int[nargs + 1];
|
||||
args[0] = nargs + 5;
|
||||
for (int i = 0; i < nargs; i++)
|
||||
args[i + 1] = i + 2;
|
||||
S.addStatement(new JavaScriptInvoke(1, nargs + 7, args, nargs + 8, cs));
|
||||
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(nargs+7, false));
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(nargs + 7, false));
|
||||
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(nargs+5, false));
|
||||
S.addStatement(SSAInstructionFactory.ReturnInstruction(nargs + 5, false));
|
||||
|
||||
return record(key, new JavaScriptConstructor(ref, S, cls));
|
||||
}
|
||||
|
||||
|
||||
private IMethod findOrCreateConstructorMethod(IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass receiver, int nargs) {
|
||||
if (receiver.getReference().equals(JavaScriptTypes.Object))
|
||||
return makeObjectConstructor(receiver, nargs);
|
||||
|
@ -512,7 +461,7 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
else if (receiver.getReference().equals(JavaScriptTypes.StringObject))
|
||||
return makeStringCall(receiver, nargs);
|
||||
else if (receiver.getReference().equals(JavaScriptTypes.NumberObject))
|
||||
return makeNumberCall(receiver, nargs);
|
||||
return makeNumberCall(receiver, nargs);
|
||||
else if (receiver.getReference().equals(JavaScriptTypes.Function))
|
||||
return makeFunctionConstructor(callerIR, callStmt, receiver, nargs);
|
||||
else {
|
||||
|
@ -520,27 +469,20 @@ public class JavaScriptConstructTargetSelector implements MethodTargetSelector {
|
|||
}
|
||||
}
|
||||
|
||||
public IMethod getCalleeTarget(CGNode caller,
|
||||
CallSiteReference site,
|
||||
IClass receiver)
|
||||
{
|
||||
public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) {
|
||||
if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) {
|
||||
Assertions._assert(cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.Root)));
|
||||
SSAContextInterpreter interpreter =
|
||||
caller.getCallGraph().getInterpreter(caller);
|
||||
IR callerIR = interpreter.getIR(caller, warnings);
|
||||
SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls( site );
|
||||
Assertions._assert( callStmts.length == 1 );
|
||||
IR callerIR = caller.getIR(warnings);
|
||||
SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls(site);
|
||||
Assertions._assert(callStmts.length == 1);
|
||||
int nargs = callStmts[0].getNumberOfUses();
|
||||
return findOrCreateConstructorMethod(callerIR, callStmts[0], receiver, nargs-1);
|
||||
return findOrCreateConstructorMethod(callerIR, callStmts[0], receiver, nargs - 1);
|
||||
} else {
|
||||
return base.getCalleeTarget(caller, site, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mightReturnSyntheticMethod(CGNode caller,
|
||||
CallSiteReference site)
|
||||
{
|
||||
public boolean mightReturnSyntheticMethod(CGNode caller, CallSiteReference site) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue