Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.ibm.wala.cast.js.ipa.summaries.JavaScriptConstructorFunctions Maven / Gradle / Ivy
/*
* Copyright (c) 2002 - 2014 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.ipa.summaries;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.ssa.JSInstructionFactory;
import com.ibm.wala.cast.js.types.JavaScriptMethods;
import com.ibm.wala.cast.js.types.JavaScriptTypes;
import com.ibm.wala.cast.loader.DynamicCallSiteReference;
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.Module;
import com.ibm.wala.classLoader.ModuleEntry;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.classLoader.SourceModule;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.summaries.MethodSummary;
import com.ibm.wala.shrike.shrikeBT.IConditionalBranchInstruction.Operator;
import com.ibm.wala.ssa.ConstantValue;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
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.HashMapFactory;
import com.ibm.wala.util.collections.NonNullSingletonIterator;
import com.ibm.wala.util.collections.Pair;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class JavaScriptConstructorFunctions {
private final Map constructors = HashMapFactory.make();
private final IClassHierarchy cha;
public JavaScriptConstructorFunctions(IClassHierarchy cha) {
this.cha = cha;
}
public static class JavaScriptConstructor extends JavaScriptSummarizedFunction {
private final 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,
IClass constructorForType) {
this(ref, summary, declaringClass, constructorForType, "");
}
@Override
public String toString() {
return "';
}
public IClass constructedType() {
return constructorForType;
}
}
private IMethod record(Object key, IMethod m) {
constructors.put(key, m);
return m;
}
private static IMethod makeNullaryValueConstructor(IClass cls, Object value) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = JavaScriptMethods.makeCtorReference(cls.getReference());
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 4, 1, "prototype"));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
5,
NewSiteReference.make(S.getNumberOfStatements(), cls.getReference())));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), 5, 4));
// S.addStatement(insts.PutInstruction(5, 4, "__proto__"));
S.getNumberOfStatements();
S.addConstant(8, new ConstantValue(value));
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 5, 8, "$value"));
if (value instanceof String) {
S.addConstant(9, new ConstantValue(0));
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 5, 9, "length"));
}
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
S.getNumberOfStatements();
// S.addConstant(9, new ConstantValue("__proto__"));
return new JavaScriptConstructor(ref, S, cls, cls);
}
private static IMethod makeUnaryValueConstructor(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = JavaScriptMethods.makeCtorReference(cls.getReference());
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 5, 1, "prototype"));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
6,
NewSiteReference.make(S.getNumberOfStatements(), cls.getReference())));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), 6, 5));
// S.addStatement(insts.PutInstruction(6, 5, "__proto__"));
S.getNumberOfStatements();
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 6, 2, "$value"));
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 6, false));
S.getNumberOfStatements();
// S.addConstant(7, new ConstantValue("__proto__"));
return new JavaScriptConstructor(ref, S, cls, cls);
}
private IMethod makeValueConstructor(IClass cls, int nargs, Object value) {
if (nargs == 0 || nargs == 1) {
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
else
return record(
key,
(nargs == 0)
? makeNullaryValueConstructor(cls, value)
: makeUnaryValueConstructor(cls));
} else {
// not a legal call, likely due to dataflow imprecision
return null;
}
}
/** create a method for constructing an Object with no arguments passed */
private IMethod makeNullaryObjectConstructor(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Object);
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 4, 1, "prototype"));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
5,
NewSiteReference.make(S.getNumberOfStatements(), JavaScriptTypes.Object)));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), 5, 4));
// S.addStatement(insts.PutInstruction(5, 4, "__proto__"));
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
S.getNumberOfStatements();
// S.addConstant(6, new ConstantValue("__proto__"));
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Object));
}
private IMethod makeUnaryObjectConstructor(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Object);
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 2, false));
S.getNumberOfStatements();
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Object));
}
private IMethod makeObjectConstructor(IClass cls, int nargs) {
if (nargs == 0 || nargs == 1) {
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
else
return record(
key,
(nargs == 0) ? makeNullaryObjectConstructor(cls) : makeUnaryObjectConstructor(cls));
} else {
// not a legal call, likely the result of analysis imprecision
return null;
}
}
private IMethod makeObjectCall(IClass cls, int nargs) {
assert nargs == 0;
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
else return record(key, makeNullaryObjectConstructor(cls));
}
private IMethod makeArrayLengthConstructor(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Array);
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 5, 1, "prototype"));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
6,
NewSiteReference.make(S.getNumberOfStatements(), JavaScriptTypes.Array)));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), 6, 5));
// S.addStatement(insts.PutInstruction(6, 5, "__proto__"));
S.getNumberOfStatements();
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 6, 2, "length"));
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 6, false));
S.getNumberOfStatements();
// S.addConstant(7, new ConstantValue("__proto__"));
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Array));
}
private IMethod makeArrayContentsConstructor(IClass cls, int nargs) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = JavaScriptMethods.makeCtorReference(JavaScriptTypes.Array);
JavaScriptSummary S = new JavaScriptSummary(ref, nargs + 1);
S.addConstant(nargs + 3, new ConstantValue("prototype"));
S.addStatement(insts.PropertyRead(S.getNumberOfStatements(), nargs + 4, 1, nargs + 3));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
nargs + 5,
NewSiteReference.make(S.getNumberOfStatements(), JavaScriptTypes.Array)));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), nargs + 5, nargs + 4));
// S.addStatement(insts.PutInstruction(nargs + 5, nargs + 4, "__proto__"));
S.getNumberOfStatements();
S.addConstant(nargs + 7, new ConstantValue(nargs));
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), nargs + 5, nargs + 7, "length"));
S.getNumberOfStatements();
int vn = nargs + 9;
for (int i = 0; i < nargs; i++, vn += 2) {
S.addConstant(vn, new ConstantValue(i));
S.addStatement(insts.PropertyWrite(S.getNumberOfStatements(), nargs + 5, vn, i + 1));
S.getNumberOfStatements();
}
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
S.getNumberOfStatements();
// S.addConstant(vn, new ConstantValue("__proto__"));
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Array));
}
private IMethod makeArrayConstructor(IClass cls, int nargs) {
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
else
return record(
key,
(nargs == 1)
? makeArrayLengthConstructor(cls)
: makeArrayContentsConstructor(cls, nargs));
}
private IMethod makeNullaryStringCall(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.String);
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
S.addConstant(2, new ConstantValue(""));
S.addConstant(3, new ConstantValue(0));
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 2, 3, "length"));
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 2, false));
S.getNumberOfStatements();
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.String));
}
private IMethod makeUnaryStringCall(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.String);
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 4, 2, "toString"));
S.getNumberOfStatements();
CallSiteReference cs =
new DynamicCallSiteReference(JavaScriptTypes.CodeBody, S.getNumberOfStatements());
S.addStatement(insts.Invoke(S.getNumberOfStatements(), 4, 5, new int[] {2}, 6, cs));
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
S.getNumberOfStatements();
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.String));
}
private IMethod makeStringCall(IClass cls, int nargs) {
assert nargs == 0 || nargs == 1;
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
else return record(key, (nargs == 0) ? makeNullaryStringCall(cls) : makeUnaryStringCall(cls));
}
private IMethod makeNullaryNumberCall(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.Number);
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
S.addConstant(2, new ConstantValue(0.0));
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 2, false));
S.getNumberOfStatements();
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Number));
}
private IMethod makeUnaryNumberCall(IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
MethodReference ref = AstMethodReference.fnReference(JavaScriptTypes.Number);
JavaScriptSummary S = new JavaScriptSummary(ref, 2);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 4, 2, "toNumber"));
S.getNumberOfStatements();
CallSiteReference cs =
new DynamicCallSiteReference(JavaScriptTypes.CodeBody, S.getNumberOfStatements());
S.addStatement(insts.Invoke(S.getNumberOfStatements(), 4, 5, new int[] {2}, 6, cs));
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
S.getNumberOfStatements();
return new JavaScriptConstructor(ref, S, cls, cha.lookupClass(JavaScriptTypes.Number));
}
private IMethod makeNumberCall(IClass cls, int nargs) {
assert nargs == 0 || nargs == 1;
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
else return record(key, (nargs == 0) ? makeNullaryNumberCall(cls) : makeUnaryNumberCall(cls));
}
private IMethod makeFunctionConstructor(IClass receiver, IClass cls) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
Pair tableKey = Pair.make(receiver, cls);
if (constructors.containsKey(tableKey)) return constructors.get(tableKey);
MethodReference ref = JavaScriptMethods.makeCtorReference(receiver.getReference());
JavaScriptSummary S = new JavaScriptSummary(ref, 1);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), 4, 1, "prototype"));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
5,
NewSiteReference.make(S.getNumberOfStatements(), cls.getReference())));
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
7,
NewSiteReference.make(S.getNumberOfStatements(), JavaScriptTypes.Object)));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), 5, 4));
// S.addStatement(insts.PutInstruction(5, 4, "__proto__"));
S.getNumberOfStatements();
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 5, 7, "prototype"));
S.getNumberOfStatements();
S.addStatement(insts.PutInstruction(S.getNumberOfStatements(), 7, 5, "constructor"));
S.getNumberOfStatements();
// TODO we need to set v7.__proto__ to Object.prototype
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), 5, false));
S.getNumberOfStatements();
// S.addConstant(8, new ConstantValue("__proto__"));
if (receiver != cls)
return record(
tableKey,
new JavaScriptConstructor(
ref, S, receiver, cls, "(" + cls.getReference().getName() + ')'));
else return record(tableKey, new JavaScriptConstructor(ref, S, receiver, cls));
}
private int ctorCount = 0;
private IMethod makeFunctionConstructor(
IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass cls, int nargs) {
SymbolTable ST = callerIR.getSymbolTable();
switch (nargs) {
case 0:
return makeFunctionConstructor(cls, cls);
case 1:
if (ST.isStringConstant(callStmt.getUse(1))
&& !ST.getStringValue(callStmt.getUse(1)).isEmpty()) {
TypeReference ref =
TypeReference.findOrCreate(
JavaScriptTypes.jsLoader,
TypeName.string2TypeName(ST.getStringValue(callStmt.getUse(1))));
IClass cls2 = cha.lookupClass(ref);
if (cls2 != null) {
return makeFunctionConstructor(cls, cls2);
}
}
return makeFunctionConstructor(cls, cls);
default:
assert nargs > 1;
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);
final StringBuilder fun = new StringBuilder("function _fromctor (");
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('}');
try {
final String fileName = "ctor$" + ++ctorCount;
ModuleEntry ME =
new SourceModule() {
@Override
public String getName() {
return fileName;
}
@Override
public boolean isClassFile() {
return false;
}
@Override
public boolean isSourceFile() {
return true;
}
@Override
public InputStream getInputStream() {
return new InputStream() {
private int i = 0;
@Override
public int read() throws IOException {
if (i >= fun.length()) {
return -1;
} else {
return fun.codePointAt(i++);
}
}
};
}
@Override
public boolean isModuleFile() {
return false;
}
@Override
public Module asModule() {
return null;
}
@Override
public String getClassName() {
return fileName;
}
@Override
public Module getContainer() {
return null;
}
@Override
public Iterator extends ModuleEntry> getEntries() {
return new NonNullSingletonIterator(this);
}
@Override
public Reader getInputReader() {
return new StringReader(fun.toString());
}
@Override
public URL getURL() {
try {
return new URL("file://" + fileName);
} catch (MalformedURLException e) {
assert false;
return null;
}
}
};
Set fnNames = JSCallGraphUtil.loadAdditionalFile(cha, cl, ME);
IClass fcls = null;
for (String nm : fnNames) {
if (nm.endsWith("_fromctor")) {
fcls = cl.lookupClass(nm, cha);
}
}
if (fcls == null) {
// This can happen, e.g., if the arguments to the Function constructor call are
// malformed.
// In this case, return a synthetic constructor similar to the 0-argument case
return makeFunctionConstructor(cls, cls);
} else {
return makeFunctionConstructor(cls, fcls);
}
} catch (IOException e) {
}
return makeFunctionConstructor(cls, cls);
}
}
private IMethod makeFunctionObjectConstructor(IClass cls, int nargs) {
JSInstructionFactory insts =
(JSInstructionFactory) cls.getClassLoader().getInstructionFactory();
Object key = Pair.make(cls, nargs);
if (constructors.containsKey(key)) return constructors.get(key);
MethodReference ref = JavaScriptMethods.makeCtorReference(cls.getReference());
JavaScriptSummary S = new JavaScriptSummary(ref, nargs + 1);
S.addStatement(insts.GetInstruction(S.getNumberOfStatements(), nargs + 4, 1, "prototype"));
S.getNumberOfStatements();
S.addStatement(
insts.NewInstruction(
S.getNumberOfStatements(),
nargs + 5,
NewSiteReference.make(S.getNumberOfStatements(), JavaScriptTypes.Object)));
S.addStatement(insts.SetPrototype(S.getNumberOfStatements(), nargs + 5, nargs + 4));
S.getNumberOfStatements();
CallSiteReference cs =
new DynamicCallSiteReference(JavaScriptTypes.CodeBody, S.getNumberOfStatements());
int[] args = new int[nargs + 1];
args[0] = nargs + 5;
for (int i = 0; i < nargs; i++) args[i + 1] = i + 2;
S.addStatement(insts.Invoke(S.getNumberOfStatements(), 1, nargs + 7, args, nargs + 8, cs));
int pc = S.getNumberOfStatements();
S.addConstant(nargs + 9, null);
S.addStatement(
insts.ConditionalBranchInstruction(
S.getNumberOfStatements(),
Operator.EQ,
JavaScriptTypes.Root,
nargs + 7,
nargs + 9,
pc + 2));
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), nargs + 7, false));
S.getNumberOfStatements();
S.addStatement(insts.ReturnInstruction(S.getNumberOfStatements(), nargs + 5, false));
S.getNumberOfStatements();
return record(key, new JavaScriptConstructor(ref, S, cls, cls));
}
public IMethod findOrCreateConstructorMethod(
IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass receiver, int nargs) {
if (receiver.getReference().equals(JavaScriptTypes.Object))
return makeObjectConstructor(receiver, nargs);
else if (receiver.getReference().equals(JavaScriptTypes.Array))
return makeArrayConstructor(receiver, nargs);
else if (receiver.getReference().equals(JavaScriptTypes.StringObject))
return makeValueConstructor(receiver, nargs, "");
else if (receiver.getReference().equals(JavaScriptTypes.BooleanObject)) {
assert nargs == 1;
return makeValueConstructor(receiver, nargs, null);
} else if (receiver.getReference().equals(JavaScriptTypes.NumberObject))
return makeValueConstructor(receiver, nargs, 0);
else if (receiver.getReference().equals(JavaScriptTypes.Function))
return makeFunctionConstructor(callerIR, callStmt, receiver, nargs);
else if (cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.CodeBody)))
return makeFunctionObjectConstructor(receiver, nargs);
else {
return null;
}
}
public IMethod findOrCreateCallMethod(
IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass receiver, int nargs) {
if (receiver.getReference().equals(JavaScriptTypes.Object))
return makeObjectCall(receiver, nargs);
else if (receiver.getReference().equals(JavaScriptTypes.Array))
return makeArrayConstructor(receiver, nargs);
else if (receiver.getReference().equals(JavaScriptTypes.StringObject))
return makeStringCall(receiver, nargs);
else if (receiver.getReference().equals(JavaScriptTypes.NumberObject))
return makeNumberCall(receiver, nargs);
else if (receiver.getReference().equals(JavaScriptTypes.Function))
return makeFunctionConstructor(callerIR, callStmt, receiver, nargs);
else {
return null;
}
}
}