use of soot.jimple.ClassConstant in project robovm by robovm.
the class LambdaPlugin method transformMethod.
private void transformMethod(Config config, Clazz clazz, SootClass sootClass, SootMethod method, ModuleBuilder moduleBuilder) throws IOException {
if (!method.isConcrete()) {
return;
}
int tmpCounter = 0;
Body body = method.retrieveActiveBody();
PatchingChain<Unit> units = body.getUnits();
for (Unit unit = units.getFirst(); unit != null; unit = body.getUnits().getSuccOf(unit)) {
if (unit instanceof DefinitionStmt) {
if (((DefinitionStmt) unit).getRightOp() instanceof DynamicInvokeExpr) {
DynamicInvokeExpr expr = (DynamicInvokeExpr) ((DefinitionStmt) unit).getRightOp();
if (isLambdaBootstrapMethod(expr.getBootstrapMethodRef())) {
LambdaClassGenerator generator = null;
synchronized (generators) {
generator = generators.get(sootClass);
if (generator == null) {
generator = new LambdaClassGenerator();
generators.put(sootClass, generator);
}
}
List<Value> bsmArgs = expr.getBootstrapArgs();
SootClass caller = sootClass;
String invokedName = expr.getMethodRef().name();
SootMethodRef invokedType = expr.getMethodRef();
SootMethodType samMethodType = (SootMethodType) bsmArgs.get(0);
SootMethodHandle implMethod = (SootMethodHandle) bsmArgs.get(1);
SootMethodType instantiatedMethodType = (SootMethodType) bsmArgs.get(2);
try {
LambdaClass callSite = null;
List<Type> markerInterfaces = new ArrayList<>();
List<SootMethodType> bridgeMethods = new ArrayList<>();
if (expr.getBootstrapMethodRef().name().equals("altMetafactory")) {
int flags = ((IntConstant) bsmArgs.get(3)).value;
int bsmArgsIdx = 4;
if ((flags & FLAG_MARKERS) > 0) {
int count = ((IntConstant) bsmArgs.get(bsmArgsIdx++)).value;
for (int i = 0; i < count; i++) {
Object value = bsmArgs.get(bsmArgsIdx++);
if (value instanceof Type) {
markerInterfaces.add((Type) value);
} else if (value instanceof ClassConstant) {
String className = ((ClassConstant) value).getValue().replace('/', '.');
markerInterfaces.add(SootResolver.v().resolveClass(className, SootClass.HIERARCHY).getType());
}
}
}
if ((flags & FLAG_BRIDGES) > 0) {
int count = ((IntConstant) bsmArgs.get(bsmArgsIdx++)).value;
for (int i = 0; i < count; i++) {
bridgeMethods.add((SootMethodType) bsmArgs.get(bsmArgsIdx++));
}
}
}
// see issue #1087
if (bridgeMethods.size() == 0) {
SootClass targetType = SootResolver.v().resolveClass(invokedType.returnType().toString().replace('/', '.'), SootClass.SIGNATURES);
String samDescriptor = Types.getDescriptor(samMethodType.getParameterTypes(), samMethodType.getReturnType());
for (SootMethod targetTypeMethod : targetType.getMethods()) {
boolean isBridgeMethod = targetTypeMethod.getName().equals(invokedName);
isBridgeMethod &= targetTypeMethod.getName().equals(invokedName);
isBridgeMethod &= targetTypeMethod.getParameterCount() == samMethodType.getParameterTypes().size();
isBridgeMethod &= ((targetTypeMethod.getModifiers() & BRIDGE) != 0);
isBridgeMethod &= ((targetTypeMethod.getModifiers() & SYNTHETIC) != 0);
if (isBridgeMethod) {
String targetTypeMethodDesc = Types.getDescriptor(targetTypeMethod);
if (!targetTypeMethodDesc.equals(samDescriptor)) {
bridgeMethods.add(new BridgeMethodType(targetTypeMethod.getReturnType(), targetTypeMethod.getParameterTypes()));
}
}
}
}
// generate the lambda class
callSite = generator.generate(caller, invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType, markerInterfaces, bridgeMethods);
File f = clazz.getPath().getGeneratedClassFile(callSite.getLambdaClassName());
FileUtils.writeByteArrayToFile(f, callSite.getClassData());
// The lambda class is created after the caller is
// compiled.
// This prevents the triggering of a recompile of
// the caller.
f.setLastModified(clazz.lastModified());
SootClass lambdaClass = SootResolver.v().makeClassRef(callSite.getLambdaClassName().replace('/', '.'));
Local l = (Local) ((DefinitionStmt) unit).getLeftOp();
Type samType = callSite.getTargetMethodReturnType();
LinkedList<Unit> newUnits = new LinkedList<>();
if (callSite.getTargetMethodName().equals("<init>")) {
// Constant lambda. Create an instance once and
// reuse for
// every call.
String fieldName = lambdaClass.getName().substring(lambdaClass.getName().lastIndexOf('.') + 1);
SootField field = new SootField(fieldName, lambdaClass.getType(), Modifier.STATIC | Modifier.PRIVATE | Modifier.TRANSIENT | 0x1000);
method.getDeclaringClass().addField(field);
// l = LambdaClass.lambdaField
newUnits.add(Jimple.v().newAssignStmt(l, Jimple.v().newStaticFieldRef(field.makeRef())));
// if l != null goto succOfInvokedynamic
newUnits.add(Jimple.v().newIfStmt(Jimple.v().newNeExpr(l, NullConstant.v()), units.getSuccOf(unit)));
// $tmpX = new LambdaClass()
Local tmp = Jimple.v().newLocal("$tmp" + (tmpCounter++), lambdaClass.getType());
body.getLocals().add(tmp);
newUnits.add(Jimple.v().newAssignStmt(tmp, Jimple.v().newNewExpr(lambdaClass.getType())));
newUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(tmp, Scene.v().makeConstructorRef(lambdaClass, Collections.<Type>emptyList()))));
// LambdaClass.lambdaField = $tmpX
newUnits.add(Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(field.makeRef()), tmp));
// l = $tmpX
newUnits.add(Jimple.v().newAssignStmt(l, tmp));
} else {
// Static factory method returns the lambda to
// use.
newUnits.add(Jimple.v().newAssignStmt(l, Jimple.v().newStaticInvokeExpr(Scene.v().makeMethodRef(lambdaClass, callSite.getTargetMethodName(), callSite.getTargetMethodParameters(), samType, true), expr.getArgs())));
}
units.insertAfter(newUnits, unit);
units.remove(unit);
unit = newUnits.getLast();
} catch (Throwable e) {
// LambdaConversionException at runtime.
throw new CompilerException(e);
}
}
}
}
}
}
use of soot.jimple.ClassConstant in project robovm by robovm.
the class ObjCMemberPlugin method addBindCall.
private void addBindCall(SootClass sootClass) {
Jimple j = Jimple.v();
SootMethod clinit = getOrCreateStaticInitializer(sootClass);
Body body = clinit.retrieveActiveBody();
String internalName = sootClass.getName().replace('.', '/');
ClassConstant c = ClassConstant.v(internalName);
Chain<Unit> units = body.getUnits();
// Don't call bind if there's already a call in the static initializer
for (Unit unit : units) {
if (unit instanceof InvokeStmt) {
InvokeStmt stmt = (InvokeStmt) unit;
if (stmt.getInvokeExpr() instanceof StaticInvokeExpr) {
StaticInvokeExpr expr = (StaticInvokeExpr) stmt.getInvokeExpr();
SootMethodRef ref = expr.getMethodRef();
if (ref.isStatic() && ref.declaringClass().equals(org_robovm_objc_ObjCRuntime) && ref.name().equals("bind")) {
if (ref.parameterTypes().isEmpty() || expr.getArg(0).equals(c)) {
return;
}
}
}
}
}
// Call ObjCRuntime.bind(<class>)
units.insertBefore(j.newInvokeStmt(j.newStaticInvokeExpr(org_robovm_objc_ObjCRuntime_bind, ClassConstant.v(internalName))), units.getLast());
}
use of soot.jimple.ClassConstant in project soot by Sable.
the class ConstraintCollector method caseAssignStmt.
public void caseAssignStmt(AssignStmt stmt) {
Value l = stmt.getLeftOp();
Value r = stmt.getRightOp();
TypeVariable left = null;
TypeVariable right = null;
if (l instanceof ArrayRef) {
ArrayRef ref = (ArrayRef) l;
Value base = ref.getBase();
Value index = ref.getIndex();
TypeVariable baseType = resolver.typeVariable((Local) base);
baseType.makeElement();
left = baseType.element();
if (index instanceof Local) {
if (uses) {
resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
}
}
} else if (l instanceof Local) {
left = resolver.typeVariable((Local) l);
} else if (l instanceof InstanceFieldRef) {
InstanceFieldRef ref = (InstanceFieldRef) l;
if (uses) {
TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
left = resolver.typeVariable(ref.getField().getType());
}
} else if (l instanceof StaticFieldRef) {
if (uses) {
StaticFieldRef ref = (StaticFieldRef) l;
left = resolver.typeVariable(ref.getField().getType());
}
} else {
throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
}
if (r instanceof ArrayRef) {
ArrayRef ref = (ArrayRef) r;
Value base = ref.getBase();
Value index = ref.getIndex();
TypeVariable baseType = resolver.typeVariable((Local) base);
baseType.makeElement();
right = baseType.element();
if (index instanceof Local) {
if (uses) {
resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
}
}
} else if (r instanceof DoubleConstant) {
right = resolver.typeVariable(DoubleType.v());
} else if (r instanceof FloatConstant) {
right = resolver.typeVariable(FloatType.v());
} else if (r instanceof IntConstant) {
right = resolver.typeVariable(IntType.v());
} else if (r instanceof LongConstant) {
right = resolver.typeVariable(LongType.v());
} else if (r instanceof NullConstant) {
right = resolver.typeVariable(NullType.v());
} else if (r instanceof StringConstant) {
right = resolver.typeVariable(RefType.v("java.lang.String"));
} else if (r instanceof ClassConstant) {
right = resolver.typeVariable(RefType.v("java.lang.Class"));
} else if (r instanceof BinopExpr) {
// ******** BINOP EXPR ********
BinopExpr be = (BinopExpr) r;
Value lv = be.getOp1();
Value rv = be.getOp2();
TypeVariable lop;
TypeVariable rop;
// ******** LEFT ********
if (lv instanceof Local) {
lop = resolver.typeVariable((Local) lv);
} else if (lv instanceof DoubleConstant) {
lop = resolver.typeVariable(DoubleType.v());
} else if (lv instanceof FloatConstant) {
lop = resolver.typeVariable(FloatType.v());
} else if (lv instanceof IntConstant) {
lop = resolver.typeVariable(IntType.v());
} else if (lv instanceof LongConstant) {
lop = resolver.typeVariable(LongType.v());
} else if (lv instanceof NullConstant) {
lop = resolver.typeVariable(NullType.v());
} else if (lv instanceof StringConstant) {
lop = resolver.typeVariable(RefType.v("java.lang.String"));
} else if (lv instanceof ClassConstant) {
lop = resolver.typeVariable(RefType.v("java.lang.Class"));
} else {
throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
}
// ******** RIGHT ********
if (rv instanceof Local) {
rop = resolver.typeVariable((Local) rv);
} else if (rv instanceof DoubleConstant) {
rop = resolver.typeVariable(DoubleType.v());
} else if (rv instanceof FloatConstant) {
rop = resolver.typeVariable(FloatType.v());
} else if (rv instanceof IntConstant) {
rop = resolver.typeVariable(IntType.v());
} else if (rv instanceof LongConstant) {
rop = resolver.typeVariable(LongType.v());
} else if (rv instanceof NullConstant) {
rop = resolver.typeVariable(NullType.v());
} else if (rv instanceof StringConstant) {
rop = resolver.typeVariable(RefType.v("java.lang.String"));
} else if (rv instanceof ClassConstant) {
rop = resolver.typeVariable(RefType.v("java.lang.Class"));
} else {
throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
}
if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof MulExpr) || (be instanceof DivExpr) || (be instanceof RemExpr) || (be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
if (uses) {
TypeVariable common = resolver.typeVariable();
rop.addParent(common);
lop.addParent(common);
}
if (left != null) {
rop.addParent(left);
lop.addParent(left);
}
} else if ((be instanceof ShlExpr) || (be instanceof ShrExpr) || (be instanceof UshrExpr)) {
if (uses) {
rop.addParent(resolver.typeVariable(IntType.v()));
}
right = lop;
} else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr) || (be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
if (uses) {
TypeVariable common = resolver.typeVariable();
rop.addParent(common);
lop.addParent(common);
}
right = resolver.typeVariable(IntType.v());
} else {
throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
}
} else if (r instanceof CastExpr) {
CastExpr ce = (CastExpr) r;
right = resolver.typeVariable(ce.getCastType());
} else if (r instanceof InstanceOfExpr) {
right = resolver.typeVariable(IntType.v());
} else if (r instanceof InvokeExpr) {
InvokeExpr ie = (InvokeExpr) r;
handleInvokeExpr(ie);
right = resolver.typeVariable(ie.getMethodRef().returnType());
} else if (r instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) r;
Type baseType = nae.getBaseType();
if (baseType instanceof ArrayType) {
right = resolver.typeVariable(ArrayType.v(((ArrayType) baseType).baseType, ((ArrayType) baseType).numDimensions + 1));
} else {
right = resolver.typeVariable(ArrayType.v(baseType, 1));
}
if (uses) {
Value size = nae.getSize();
if (size instanceof Local) {
TypeVariable var = resolver.typeVariable((Local) size);
var.addParent(resolver.typeVariable(IntType.v()));
}
}
} else if (r instanceof NewExpr) {
NewExpr na = (NewExpr) r;
right = resolver.typeVariable(na.getBaseType());
} else if (r instanceof NewMultiArrayExpr) {
NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
right = resolver.typeVariable(nmae.getBaseType());
if (uses) {
for (int i = 0; i < nmae.getSizeCount(); i++) {
Value size = nmae.getSize(i);
if (size instanceof Local) {
TypeVariable var = resolver.typeVariable((Local) size);
var.addParent(resolver.typeVariable(IntType.v()));
}
}
}
} else if (r instanceof LengthExpr) {
LengthExpr le = (LengthExpr) r;
if (uses) {
if (le.getOp() instanceof Local) {
resolver.typeVariable((Local) le.getOp()).makeElement();
}
}
right = resolver.typeVariable(IntType.v());
} else if (r instanceof NegExpr) {
NegExpr ne = (NegExpr) r;
if (ne.getOp() instanceof Local) {
right = resolver.typeVariable((Local) ne.getOp());
} else if (ne.getOp() instanceof DoubleConstant) {
right = resolver.typeVariable(DoubleType.v());
} else if (ne.getOp() instanceof FloatConstant) {
right = resolver.typeVariable(FloatType.v());
} else if (ne.getOp() instanceof IntConstant) {
right = resolver.typeVariable(IntType.v());
} else if (ne.getOp() instanceof LongConstant) {
right = resolver.typeVariable(LongType.v());
} else {
throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
}
} else if (r instanceof Local) {
right = resolver.typeVariable((Local) r);
} else if (r instanceof InstanceFieldRef) {
InstanceFieldRef ref = (InstanceFieldRef) r;
if (uses) {
TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
}
right = resolver.typeVariable(ref.getField().getType());
} else if (r instanceof StaticFieldRef) {
StaticFieldRef ref = (StaticFieldRef) r;
right = resolver.typeVariable(ref.getField().getType());
} else {
throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
}
if (left != null && right != null) {
right.addParent(left);
}
}
use of soot.jimple.ClassConstant in project soot by Sable.
the class ConstraintCollector method caseIfStmt.
public void caseIfStmt(IfStmt stmt) {
if (uses) {
ConditionExpr cond = (ConditionExpr) stmt.getCondition();
BinopExpr expr = cond;
Value lv = expr.getOp1();
Value rv = expr.getOp2();
TypeVariable lop;
TypeVariable rop;
// ******** LEFT ********
if (lv instanceof Local) {
lop = resolver.typeVariable((Local) lv);
} else if (lv instanceof DoubleConstant) {
lop = resolver.typeVariable(DoubleType.v());
} else if (lv instanceof FloatConstant) {
lop = resolver.typeVariable(FloatType.v());
} else if (lv instanceof IntConstant) {
lop = resolver.typeVariable(IntType.v());
} else if (lv instanceof LongConstant) {
lop = resolver.typeVariable(LongType.v());
} else if (lv instanceof NullConstant) {
lop = resolver.typeVariable(NullType.v());
} else if (lv instanceof StringConstant) {
lop = resolver.typeVariable(RefType.v("java.lang.String"));
} else if (lv instanceof ClassConstant) {
lop = resolver.typeVariable(RefType.v("java.lang.Class"));
} else {
throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
}
// ******** RIGHT ********
if (rv instanceof Local) {
rop = resolver.typeVariable((Local) rv);
} else if (rv instanceof DoubleConstant) {
rop = resolver.typeVariable(DoubleType.v());
} else if (rv instanceof FloatConstant) {
rop = resolver.typeVariable(FloatType.v());
} else if (rv instanceof IntConstant) {
rop = resolver.typeVariable(IntType.v());
} else if (rv instanceof LongConstant) {
rop = resolver.typeVariable(LongType.v());
} else if (rv instanceof NullConstant) {
rop = resolver.typeVariable(NullType.v());
} else if (rv instanceof StringConstant) {
rop = resolver.typeVariable(RefType.v("java.lang.String"));
} else if (rv instanceof ClassConstant) {
rop = resolver.typeVariable(RefType.v("java.lang.Class"));
} else {
throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
}
TypeVariable common = resolver.typeVariable();
rop.addParent(common);
lop.addParent(common);
}
}
use of soot.jimple.ClassConstant in project soot by Sable.
the class ConstraintCollector method caseAssignStmt.
public void caseAssignStmt(AssignStmt stmt) {
Value l = stmt.getLeftOp();
Value r = stmt.getRightOp();
TypeVariable left = null;
TypeVariable right = null;
if (l instanceof ArrayRef) {
ArrayRef ref = (ArrayRef) l;
Type baset = ((Local) ref.getBase()).getType();
if (baset instanceof ArrayType) {
ArrayType base = (ArrayType) baset;
Value index = ref.getIndex();
if (uses) {
if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
left = resolver.typeVariable(base.baseType);
}
if (index instanceof Local) {
resolver.typeVariable((Local) index).addParent(resolver.INT);
}
}
}
} else if (l instanceof Local) {
if (((Local) l).getType() instanceof IntegerType) {
left = resolver.typeVariable((Local) l);
}
} else if (l instanceof InstanceFieldRef) {
if (uses) {
InstanceFieldRef ref = (InstanceFieldRef) l;
Type fieldType = ref.getFieldRef().type();
if (fieldType instanceof IntegerType) {
left = resolver.typeVariable(ref.getFieldRef().type());
}
}
} else if (l instanceof StaticFieldRef) {
if (uses) {
StaticFieldRef ref = (StaticFieldRef) l;
Type fieldType = ref.getFieldRef().type();
if (fieldType instanceof IntegerType) {
left = resolver.typeVariable(ref.getFieldRef().type());
}
}
} else {
throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
}
if (r instanceof ArrayRef) {
ArrayRef ref = (ArrayRef) r;
Type baset = ((Local) ref.getBase()).getType();
if (!(baset instanceof NullType)) {
Value index = ref.getIndex();
// Be careful, dex can do some weird object/array casting
if (baset instanceof ArrayType) {
ArrayType base = (ArrayType) baset;
if ((base.numDimensions == 1) && (base.baseType instanceof IntegerType)) {
right = resolver.typeVariable(base.baseType);
}
} else if (baset instanceof IntegerType)
right = resolver.typeVariable(baset);
if (uses)
if (index instanceof Local)
resolver.typeVariable((Local) index).addParent(resolver.INT);
}
} else if (r instanceof DoubleConstant) {
} else if (r instanceof FloatConstant) {
} else if (r instanceof IntConstant) {
int value = ((IntConstant) r).value;
if (value < -32768) {
right = resolver.INT;
} else if (value < -128) {
right = resolver.SHORT;
} else if (value < 0) {
right = resolver.BYTE;
} else if (value < 2) {
right = resolver.R0_1;
} else if (value < 128) {
right = resolver.R0_127;
} else if (value < 32768) {
right = resolver.R0_32767;
} else if (value < 65536) {
right = resolver.CHAR;
} else {
right = resolver.INT;
}
} else if (r instanceof LongConstant) {
} else if (r instanceof NullConstant) {
} else if (r instanceof StringConstant) {
} else if (r instanceof ClassConstant) {
} else if (r instanceof BinopExpr) {
// ******** BINOP EXPR ********
BinopExpr be = (BinopExpr) r;
Value lv = be.getOp1();
Value rv = be.getOp2();
TypeVariable lop = null;
TypeVariable rop = null;
// ******** LEFT ********
if (lv instanceof Local) {
if (((Local) lv).getType() instanceof IntegerType) {
lop = resolver.typeVariable((Local) lv);
}
} else if (lv instanceof DoubleConstant) {
} else if (lv instanceof FloatConstant) {
} else if (lv instanceof IntConstant) {
int value = ((IntConstant) lv).value;
if (value < -32768) {
lop = resolver.INT;
} else if (value < -128) {
lop = resolver.SHORT;
} else if (value < 0) {
lop = resolver.BYTE;
} else if (value < 2) {
lop = resolver.R0_1;
} else if (value < 128) {
lop = resolver.R0_127;
} else if (value < 32768) {
lop = resolver.R0_32767;
} else if (value < 65536) {
lop = resolver.CHAR;
} else {
lop = resolver.INT;
}
} else if (lv instanceof LongConstant) {
} else if (lv instanceof NullConstant) {
} else if (lv instanceof StringConstant) {
} else if (lv instanceof ClassConstant) {
} else {
throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
}
// ******** RIGHT ********
if (rv instanceof Local) {
if (((Local) rv).getType() instanceof IntegerType) {
rop = resolver.typeVariable((Local) rv);
}
} else if (rv instanceof DoubleConstant) {
} else if (rv instanceof FloatConstant) {
} else if (rv instanceof IntConstant) {
int value = ((IntConstant) rv).value;
if (value < -32768) {
rop = resolver.INT;
} else if (value < -128) {
rop = resolver.SHORT;
} else if (value < 0) {
rop = resolver.BYTE;
} else if (value < 2) {
rop = resolver.R0_1;
} else if (value < 128) {
rop = resolver.R0_127;
} else if (value < 32768) {
rop = resolver.R0_32767;
} else if (value < 65536) {
rop = resolver.CHAR;
} else {
rop = resolver.INT;
}
} else if (rv instanceof LongConstant) {
} else if (rv instanceof NullConstant) {
} else if (rv instanceof StringConstant) {
} else if (rv instanceof ClassConstant) {
} else {
throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
}
if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof DivExpr) || (be instanceof RemExpr) || (be instanceof MulExpr)) {
if (lop != null && rop != null) {
if (uses) {
if (lop.type() == null) {
lop.addParent(resolver.INT);
}
if (rop.type() == null) {
rop.addParent(resolver.INT);
}
}
right = resolver.INT;
}
} else if ((be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
if (lop != null && rop != null) {
TypeVariable common = resolver.typeVariable();
if (rop != null)
rop.addParent(common);
if (lop != null)
lop.addParent(common);
right = common;
}
} else if (be instanceof ShlExpr) {
if (uses) {
if (lop != null && lop.type() == null) {
lop.addParent(resolver.INT);
}
if (rop.type() == null) {
rop.addParent(resolver.INT);
}
}
right = (lop == null) ? null : resolver.INT;
} else if ((be instanceof ShrExpr) || (be instanceof UshrExpr)) {
if (uses) {
if (lop != null && lop.type() == null) {
lop.addParent(resolver.INT);
}
if (rop.type() == null) {
rop.addParent(resolver.INT);
}
}
right = lop;
} else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr)) {
right = resolver.BYTE;
} else if ((be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
if (uses) {
TypeVariable common = resolver.typeVariable();
if (rop != null)
rop.addParent(common);
if (lop != null)
lop.addParent(common);
}
right = resolver.BOOLEAN;
} else {
throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
}
} else if (r instanceof CastExpr) {
CastExpr ce = (CastExpr) r;
if (ce.getCastType() instanceof IntegerType) {
right = resolver.typeVariable(ce.getCastType());
}
} else if (r instanceof InstanceOfExpr) {
right = resolver.BOOLEAN;
} else if (r instanceof InvokeExpr) {
InvokeExpr ie = (InvokeExpr) r;
handleInvokeExpr(ie);
if (ie.getMethodRef().returnType() instanceof IntegerType) {
right = resolver.typeVariable(ie.getMethodRef().returnType());
}
} else if (r instanceof NewArrayExpr) {
NewArrayExpr nae = (NewArrayExpr) r;
if (uses) {
Value size = nae.getSize();
if (size instanceof Local) {
TypeVariable var = resolver.typeVariable((Local) size);
var.addParent(resolver.INT);
}
}
} else if (r instanceof NewExpr) {
} else if (r instanceof NewMultiArrayExpr) {
NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
if (uses) {
for (int i = 0; i < nmae.getSizeCount(); i++) {
Value size = nmae.getSize(i);
if (size instanceof Local) {
TypeVariable var = resolver.typeVariable((Local) size);
var.addParent(resolver.INT);
}
}
}
} else if (r instanceof LengthExpr) {
right = resolver.INT;
} else if (r instanceof NegExpr) {
NegExpr ne = (NegExpr) r;
if (ne.getOp() instanceof Local) {
Local local = (Local) ne.getOp();
if (local.getType() instanceof IntegerType) {
if (uses) {
resolver.typeVariable(local).addParent(resolver.INT);
}
TypeVariable v = resolver.typeVariable();
v.addChild(resolver.BYTE);
v.addChild(resolver.typeVariable(local));
right = v;
}
} else if (ne.getOp() instanceof DoubleConstant) {
} else if (ne.getOp() instanceof FloatConstant) {
} else if (ne.getOp() instanceof IntConstant) {
int value = ((IntConstant) ne.getOp()).value;
if (value < -32768) {
right = resolver.INT;
} else if (value < -128) {
right = resolver.SHORT;
} else if (value < 0) {
right = resolver.BYTE;
} else if (value < 2) {
right = resolver.BYTE;
} else if (value < 128) {
right = resolver.BYTE;
} else if (value < 32768) {
right = resolver.SHORT;
} else if (value < 65536) {
right = resolver.INT;
} else {
right = resolver.INT;
}
} else if (ne.getOp() instanceof LongConstant) {
} else {
throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
}
} else if (r instanceof Local) {
Local local = (Local) r;
if (local.getType() instanceof IntegerType) {
right = resolver.typeVariable(local);
}
} else if (r instanceof InstanceFieldRef) {
InstanceFieldRef ref = (InstanceFieldRef) r;
if (ref.getFieldRef().type() instanceof IntegerType) {
right = resolver.typeVariable(ref.getFieldRef().type());
}
} else if (r instanceof StaticFieldRef) {
StaticFieldRef ref = (StaticFieldRef) r;
if (ref.getFieldRef().type() instanceof IntegerType) {
right = resolver.typeVariable(ref.getFieldRef().type());
}
} else {
throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
}
if (left != null && right != null && (left.type() == null || right.type() == null)) {
right.addParent(left);
}
}
Aggregations