WALA/com.ibm.wala.cast.js/source/com/ibm/wala/cast/js/ssa/JavaScriptInvoke.java

193 lines
5.1 KiB
Java

/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.cast.js.ssa;
import java.util.Collection;
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;
import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SymbolTable;
import com.ibm.wala.types.TypeReference;
public class JavaScriptInvoke extends MultiReturnValueInvokeInstruction {
/**
* The value numbers of the arguments passed to the call.
*/
private final int[] params;
private int function;
public JavaScriptInvoke(int iindex, int function, int results[], int[] params, int exception, CallSiteReference site) {
super(iindex, results, exception, site);
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);
}
public JavaScriptInvoke(int iindex, int function, int[] params, int exception, CallSiteReference site) {
this(iindex, function, null, params, exception, site);
}
@Override
public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses) {
int fn = function;
int newParams[] = params;
if (uses != null) {
int i = 0;
fn = uses[i++];
newParams = new int[params.length];
for (int j = 0; j < newParams.length; j++)
newParams[j] = uses[i++];
}
int newLvals[] = new int[results.length];
System.arraycopy(results, 0, newLvals, 0, results.length);
int newExp = exception;
if (defs != null) {
int i = 0;
if (getNumberOfReturnValues() > 0) {
newLvals[0] = defs[i++];
}
newExp = defs[i++];
for (int j = 1; j < getNumberOfReturnValues(); j++) {
newLvals[j] = defs[i++];
}
}
return ((JSInstructionFactory)insts).Invoke(iindex, fn, newLvals, newParams, newExp, site);
}
@Override
public int getNumberOfUses() {
return getNumberOfPositionalParameters();
}
@Override
public String toString(SymbolTable symbolTable) {
StringBuffer s = new StringBuffer();
if (getNumberOfReturnValues() > 0) {
s.append(getValueString(symbolTable, getReturnValue(0)));
s.append(" = ");
}
if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference))
s.append("construct ");
else if (site.getDeclaredTarget().equals(JavaScriptMethods.dispatchReference))
s.append("dispatch ");
else
s.append("invoke ");
s.append(getValueString(symbolTable, function));
if (site != null)
s.append("@").append(site.getProgramCounter());
if (params != null) {
if (params.length > 0) {
s.append(" ").append(getValueString(symbolTable, params[0]));
}
for (int i = 1; i < params.length; i++) {
s.append(",").append(getValueString(symbolTable, params[i]));
}
}
if (exception == -1) {
s.append(" exception: NOT MODELED");
} else {
s.append(" exception:").append(getValueString(symbolTable, exception));
}
return s.toString();
}
@Override
public void visit(IVisitor v) {
assert v instanceof JSInstructionVisitor;
((JSInstructionVisitor) v).visitJavaScriptInvoke(this);
}
@Override
public int getNumberOfPositionalParameters() {
if (params == null) {
return 1;
} else {
return params.length + 1;
}
}
@Override
public int getUse(int j) {
if (j == 0)
return function;
else if (j <= params.length)
return params[j - 1];
else {
return super.getUse(j);
}
}
public int getFunction() {
return function;
}
/*
* (non-Javadoc)
* @see com.ibm.domo.ssa.Instruction#getExceptionTypes()
*/
@Override
public Collection<TypeReference> getExceptionTypes() {
return Util.typeErrorExceptions();
}
@Override
public int hashCode() {
return site.hashCode() * function * 7529;
}
// public boolean equals(Object obj) {
// if (obj instanceof JavaScriptInvoke) {
// JavaScriptInvoke other = (JavaScriptInvoke)obj;
// if (site.equals(other.site)) {
// if (getNumberOfUses() == other.getNumberOfUses()) {
// for(int i = 0; i < getNumberOfUses(); i++) {
// if (getUse(i) != other.getUse(i)) {
// return false;
// }
// }
//
// if (getNumberOfDefs() == other.getNumberOfDefs()) {
// for(int i = 0; i < getNumberOfDefs(); i++) {
// if (getDef(i) != other.getDef(i)) {
// return false;
// }
// }
//
// return true;
// }
// }
// }
// }
//
// return false;
// }
}