use of soot.jimple.NewMultiArrayExpr in project robovm by robovm.
the class MethodCompiler method assign.
private void assign(DefinitionStmt stmt) {
/*
* leftOp is either a Local, an ArrayRef or a FieldRef
* rightOp is either a Local, a Ref, or an Expr
*/
soot.Value rightOp = stmt.getRightOp();
Value result;
if (rightOp instanceof Immediate) {
Immediate immediate = (Immediate) rightOp;
result = immediate(stmt, immediate);
} else if (rightOp instanceof ThisRef) {
result = function.getParameterRef(1);
} else if (rightOp instanceof ParameterRef) {
ParameterRef ref = (ParameterRef) rightOp;
int index = (sootMethod.isStatic() ? 1 : 2) + ref.getIndex();
Value p = new VariableRef("p" + index, getType(ref.getType()));
result = widenToI32Value(stmt, p, isUnsigned(ref.getType()));
} else if (rightOp instanceof CaughtExceptionRef) {
result = call(stmt, BC_EXCEPTION_CLEAR, env);
} else if (rightOp instanceof ArrayRef) {
ArrayRef ref = (ArrayRef) rightOp;
VariableRef base = (VariableRef) immediate(stmt, (Immediate) ref.getBase());
if (ref.getType() instanceof NullType) {
// The base value is always null. Do a null check which will
// always throw NPE.
checkNull(stmt, base);
return;
} else {
Value index = immediate(stmt, (Immediate) ref.getIndex());
checkNull(stmt, base);
checkBounds(stmt, base, index);
result = call(stmt, getArrayLoad(ref.getType()), base, index);
result = widenToI32Value(stmt, result, isUnsigned(ref.getType()));
}
} else if (rightOp instanceof InstanceFieldRef) {
InstanceFieldRef ref = (InstanceFieldRef) rightOp;
Value base = immediate(stmt, (Immediate) ref.getBase());
checkNull(stmt, base);
FunctionRef fn = null;
if (canAccessDirectly(ref)) {
fn = new FunctionRef(Symbols.getterSymbol(ref.getFieldRef()), new FunctionType(getType(ref.getType()), ENV_PTR, OBJECT_PTR));
} else {
soot.Type runtimeType = ref.getBase().getType();
String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
Trampoline trampoline = new GetField(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()), runtimeClassName);
trampolines.add(trampoline);
fn = trampoline.getFunctionRef();
}
result = call(stmt, fn, env, base);
result = widenToI32Value(stmt, result, isUnsigned(ref.getType()));
} else if (rightOp instanceof StaticFieldRef) {
StaticFieldRef ref = (StaticFieldRef) rightOp;
FunctionRef fn = config.isDebug() ? null : Intrinsics.getIntrinsic(sootMethod, stmt);
if (fn == null) {
if (canAccessDirectly(ref)) {
fn = new FunctionRef(Symbols.getterSymbol(ref.getFieldRef()), new FunctionType(getType(ref.getType()), ENV_PTR));
} else {
String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
Trampoline trampoline = new GetStatic(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()));
trampolines.add(trampoline);
fn = trampoline.getFunctionRef();
}
}
result = call(stmt, fn, env);
result = widenToI32Value(stmt, result, isUnsigned(ref.getType()));
} else if (rightOp instanceof Expr) {
if (rightOp instanceof BinopExpr) {
BinopExpr expr = (BinopExpr) rightOp;
Type rightType = getLocalType(expr.getType());
Variable resultVar = function.newVariable(rightType);
result = resultVar.ref();
Value op1 = immediate(stmt, (Immediate) expr.getOp1());
Value op2 = immediate(stmt, (Immediate) expr.getOp2());
if (rightOp instanceof AddExpr) {
if (rightType instanceof IntegerType) {
function.add(new Add(resultVar, op1, op2)).attach(stmt);
} else {
function.add(new Fadd(resultVar, op1, op2)).attach(stmt);
}
} else if (rightOp instanceof AndExpr) {
function.add(new And(resultVar, op1, op2)).attach(stmt);
} else if (rightOp instanceof CmpExpr) {
Variable t1 = function.newVariable(I1);
Variable t2 = function.newVariable(I1);
Variable t3 = function.newVariable(resultVar.getType());
Variable t4 = function.newVariable(resultVar.getType());
function.add(new Icmp(t1, Condition.slt, op1, op2)).attach(stmt);
function.add(new Icmp(t2, Condition.sgt, op1, op2)).attach(stmt);
function.add(new Zext(t3, new VariableRef(t1), resultVar.getType())).attach(stmt);
function.add(new Zext(t4, new VariableRef(t2), resultVar.getType())).attach(stmt);
function.add(new Sub(resultVar, new VariableRef(t4), new VariableRef(t3))).attach(stmt);
} else if (rightOp instanceof DivExpr) {
if (rightType instanceof IntegerType) {
FunctionRef f = rightType == I64 ? LDIV : IDIV;
result = call(stmt, f, env, op1, op2);
} else {
// float or double
function.add(new Fdiv(resultVar, op1, op2)).attach(stmt);
}
} else if (rightOp instanceof MulExpr) {
if (rightType instanceof IntegerType) {
function.add(new Mul(resultVar, op1, op2)).attach(stmt);
} else {
function.add(new Fmul(resultVar, op1, op2)).attach(stmt);
}
} else if (rightOp instanceof OrExpr) {
function.add(new Or(resultVar, op1, op2)).attach(stmt);
} else if (rightOp instanceof RemExpr) {
if (rightType instanceof IntegerType) {
FunctionRef f = rightType == I64 ? LREM : IREM;
result = call(stmt, f, env, op1, op2);
} else {
FunctionRef f = rightType == DOUBLE ? DREM : FREM;
result = call(stmt, f, env, op1, op2);
}
} else if (rightOp instanceof ShlExpr || rightOp instanceof ShrExpr || rightOp instanceof UshrExpr) {
IntegerType type = (IntegerType) op1.getType();
int bits = type.getBits();
Variable t = function.newVariable(op2.getType());
function.add(new And(t, op2, new IntegerConstant(bits - 1, (IntegerType) op2.getType()))).attach(stmt);
Value shift = t.ref();
if (((IntegerType) shift.getType()).getBits() < bits) {
Variable tmp = function.newVariable(type);
function.add(new Zext(tmp, shift, type)).attach(stmt);
shift = tmp.ref();
}
if (rightOp instanceof ShlExpr) {
function.add(new Shl(resultVar, op1, shift)).attach(stmt);
} else if (rightOp instanceof ShrExpr) {
function.add(new Ashr(resultVar, op1, shift)).attach(stmt);
} else {
function.add(new Lshr(resultVar, op1, shift)).attach(stmt);
}
} else if (rightOp instanceof SubExpr) {
if (rightType instanceof IntegerType) {
function.add(new Sub(resultVar, op1, op2)).attach(stmt);
} else {
function.add(new Fsub(resultVar, op1, op2)).attach(stmt);
}
} else if (rightOp instanceof XorExpr) {
function.add(new Xor(resultVar, op1, op2)).attach(stmt);
} else if (rightOp instanceof XorExpr) {
function.add(new Xor(resultVar, op1, op2)).attach(stmt);
} else if (rightOp instanceof CmplExpr) {
FunctionRef f = op1.getType() == FLOAT ? FCMPL : DCMPL;
function.add(new Call(resultVar, f, op1, op2)).attach(stmt);
} else if (rightOp instanceof CmpgExpr) {
FunctionRef f = op1.getType() == FLOAT ? FCMPG : DCMPG;
function.add(new Call(resultVar, f, op1, op2)).attach(stmt);
} else {
throw new IllegalArgumentException("Unknown type for rightOp: " + rightOp.getClass());
}
} else if (rightOp instanceof CastExpr) {
Value op = immediate(stmt, (Immediate) ((CastExpr) rightOp).getOp());
soot.Type sootTargetType = ((CastExpr) rightOp).getCastType();
soot.Type sootSourceType = ((CastExpr) rightOp).getOp().getType();
if (sootTargetType instanceof PrimType) {
Type targetType = getType(sootTargetType);
Type sourceType = getType(sootSourceType);
if (targetType instanceof IntegerType && sourceType instanceof IntegerType) {
// op is at least I32 and has already been widened if source type had fewer bits then I32
IntegerType toType = (IntegerType) targetType;
IntegerType fromType = (IntegerType) op.getType();
Variable v = function.newVariable(toType);
if (fromType.getBits() < toType.getBits()) {
// Widening
if (isUnsigned(sootSourceType)) {
function.add(new Zext(v, op, toType)).attach(stmt);
} else {
function.add(new Sext(v, op, toType)).attach(stmt);
}
} else if (fromType.getBits() == toType.getBits()) {
function.add(new Bitcast(v, op, toType)).attach(stmt);
} else {
// Narrow
function.add(new Trunc(v, op, toType)).attach(stmt);
}
result = widenToI32Value(stmt, v.ref(), isUnsigned(sootTargetType));
} else if (targetType instanceof FloatingPointType && sourceType instanceof IntegerType) {
// we always to a signed conversion since if op is char it has already been zero extended to I32
Variable v = function.newVariable(targetType);
function.add(new Sitofp(v, op, targetType)).attach(stmt);
result = v.ref();
} else if (targetType instanceof FloatingPointType && sourceType instanceof FloatingPointType) {
Variable v = function.newVariable(targetType);
if (targetType == FLOAT && sourceType == DOUBLE) {
function.add(new Fptrunc(v, op, targetType)).attach(stmt);
} else if (targetType == DOUBLE && sourceType == FLOAT) {
function.add(new Fpext(v, op, targetType)).attach(stmt);
} else {
function.add(new Bitcast(v, op, targetType)).attach(stmt);
}
result = v.ref();
} else {
// F2I, F2L, D2I, D2L
FunctionRef f = null;
if (targetType == I32 && sourceType == FLOAT) {
f = F2I;
} else if (targetType == I64 && sourceType == FLOAT) {
f = F2L;
} else if (targetType == I32 && sourceType == DOUBLE) {
f = D2I;
} else if (targetType == I64 && sourceType == DOUBLE) {
f = D2L;
} else {
throw new IllegalArgumentException();
}
Variable v = function.newVariable(targetType);
function.add(new Call(v, f, op)).attach(stmt);
result = v.ref();
}
} else {
if (sootTargetType instanceof soot.ArrayType && ((soot.ArrayType) sootTargetType).getElementType() instanceof PrimType) {
soot.Type primType = ((soot.ArrayType) sootTargetType).getElementType();
GlobalRef arrayClassPtr = new GlobalRef("array_" + getDescriptor(primType), CLASS_PTR);
Variable arrayClass = function.newVariable(CLASS_PTR);
function.add(new Load(arrayClass, arrayClassPtr)).attach(stmt);
result = call(stmt, CHECKCAST_PRIM_ARRAY, env, arrayClass.ref(), op);
} else {
String targetClassName = getInternalName(sootTargetType);
Trampoline trampoline = new Checkcast(this.className, targetClassName);
trampolines.add(trampoline);
result = call(stmt, trampoline.getFunctionRef(), env, op);
}
}
} else if (rightOp instanceof InstanceOfExpr) {
Value op = immediate(stmt, (Immediate) ((InstanceOfExpr) rightOp).getOp());
soot.Type checkType = ((InstanceOfExpr) rightOp).getCheckType();
if (checkType instanceof soot.ArrayType && ((soot.ArrayType) checkType).getElementType() instanceof PrimType) {
soot.Type primType = ((soot.ArrayType) checkType).getElementType();
GlobalRef arrayClassPtr = new GlobalRef("array_" + getDescriptor(primType), CLASS_PTR);
Variable arrayClass = function.newVariable(CLASS_PTR);
function.add(new Load(arrayClass, arrayClassPtr)).attach(stmt);
result = call(stmt, INSTANCEOF_PRIM_ARRAY, env, arrayClass.ref(), op);
} else {
String targetClassName = getInternalName(checkType);
Trampoline trampoline = new Instanceof(this.className, targetClassName);
trampolines.add(trampoline);
result = call(stmt, trampoline.getFunctionRef(), env, op);
}
} else if (rightOp instanceof NewExpr) {
String targetClassName = getInternalName(((NewExpr) rightOp).getBaseType());
FunctionRef fn = null;
if (targetClassName.equals(this.className)) {
fn = FunctionBuilder.allocator(sootMethod.getDeclaringClass()).ref();
} else {
Trampoline trampoline = new New(this.className, targetClassName);
trampolines.add(trampoline);
fn = trampoline.getFunctionRef();
}
result = call(stmt, fn, env);
} else if (rightOp instanceof NewArrayExpr) {
NewArrayExpr expr = (NewArrayExpr) rightOp;
Value size = immediate(stmt, (Immediate) expr.getSize());
if (expr.getBaseType() instanceof PrimType) {
result = call(stmt, getNewArray(expr.getBaseType()), env, size);
} else {
String targetClassName = getInternalName(expr.getType());
Trampoline trampoline = new Anewarray(this.className, targetClassName);
trampolines.add(trampoline);
result = call(stmt, trampoline.getFunctionRef(), env, size);
}
} else if (rightOp instanceof NewMultiArrayExpr) {
NewMultiArrayExpr expr = (NewMultiArrayExpr) rightOp;
if (expr.getBaseType().numDimensions == 1 && expr.getBaseType().getElementType() instanceof PrimType) {
Value size = immediate(stmt, (Immediate) expr.getSize(0));
result = call(stmt, getNewArray(expr.getBaseType().getElementType()), env, size);
} else {
for (int i = 0; i < expr.getSizeCount(); i++) {
Value size = immediate(stmt, (Immediate) expr.getSize(i));
Variable ptr = function.newVariable(new PointerType(I32));
function.add(new Getelementptr(ptr, dims.ref(), 0, i)).attach(stmt);
function.add(new Store(size, ptr.ref())).attach(stmt);
}
Variable dimsI32 = function.newVariable(new PointerType(I32));
function.add(new Bitcast(dimsI32, dims.ref(), dimsI32.getType())).attach(stmt);
String targetClassName = getInternalName(expr.getType());
Trampoline trampoline = new Multianewarray(this.className, targetClassName);
trampolines.add(trampoline);
result = call(stmt, trampoline.getFunctionRef(), env, new IntegerConstant(expr.getSizeCount()), dimsI32.ref());
}
} else if (rightOp instanceof InvokeExpr) {
result = invokeExpr(stmt, (InvokeExpr) rightOp);
} else if (rightOp instanceof LengthExpr) {
Value op = immediate(stmt, (Immediate) ((LengthExpr) rightOp).getOp());
checkNull(stmt, op);
Variable v = function.newVariable(I32);
function.add(new Call(v, ARRAY_LENGTH, op)).attach(stmt);
result = v.ref();
} else if (rightOp instanceof NegExpr) {
NegExpr expr = (NegExpr) rightOp;
Value op = immediate(stmt, (Immediate) expr.getOp());
Type rightType = op.getType();
Variable v = function.newVariable(op.getType());
if (rightType instanceof IntegerType) {
function.add(new Sub(v, new IntegerConstant(0, (IntegerType) rightType), op)).attach(stmt);
} else {
function.add(new Fmul(v, new FloatingPointConstant(-1.0, (FloatingPointType) rightType), op)).attach(stmt);
}
result = v.ref();
} else {
throw new IllegalArgumentException("Unknown type for rightOp: " + rightOp.getClass());
}
} else {
throw new IllegalArgumentException("Unknown type for rightOp: " + rightOp.getClass());
}
soot.Value leftOp = stmt.getLeftOp();
if (leftOp instanceof Local) {
Local local = (Local) leftOp;
VariableRef v = new VariableRef(local.getName(), new PointerType(getLocalType(leftOp.getType())));
function.add(new Store(result, v, !sootMethod.getActiveBody().getTraps().isEmpty())).attach(stmt);
} else {
Type leftType = getType(leftOp.getType());
Value narrowedResult = narrowFromI32Value(stmt, leftType, result);
if (leftOp instanceof ArrayRef) {
ArrayRef ref = (ArrayRef) leftOp;
VariableRef base = (VariableRef) immediate(stmt, (Immediate) ref.getBase());
Value index = immediate(stmt, (Immediate) ref.getIndex());
checkNull(stmt, base);
checkBounds(stmt, base, index);
if (leftOp.getType() instanceof RefLikeType) {
call(stmt, BC_SET_OBJECT_ARRAY_ELEMENT, env, base, index, narrowedResult);
} else {
call(stmt, getArrayStore(leftOp.getType()), base, index, narrowedResult);
}
} else if (leftOp instanceof InstanceFieldRef) {
InstanceFieldRef ref = (InstanceFieldRef) leftOp;
Value base = immediate(stmt, (Immediate) ref.getBase());
checkNull(stmt, base);
FunctionRef fn = null;
if (canAccessDirectly(ref)) {
fn = new FunctionRef(Symbols.setterSymbol(ref.getFieldRef()), new FunctionType(VOID, ENV_PTR, OBJECT_PTR, getType(ref.getType())));
} else {
soot.Type runtimeType = ref.getBase().getType();
String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
Trampoline trampoline = new PutField(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()), runtimeClassName);
trampolines.add(trampoline);
fn = trampoline.getFunctionRef();
}
call(stmt, fn, env, base, narrowedResult);
} else if (leftOp instanceof StaticFieldRef) {
StaticFieldRef ref = (StaticFieldRef) leftOp;
FunctionRef fn = null;
if (canAccessDirectly(ref)) {
fn = new FunctionRef(Symbols.setterSymbol(ref.getFieldRef()), new FunctionType(VOID, ENV_PTR, getType(ref.getType())));
} else {
String targetClassName = getInternalName(ref.getFieldRef().declaringClass());
Trampoline trampoline = new PutStatic(this.className, targetClassName, ref.getFieldRef().name(), getDescriptor(ref.getFieldRef().type()));
trampolines.add(trampoline);
fn = trampoline.getFunctionRef();
}
call(stmt, fn, env, narrowedResult);
} else {
throw new IllegalArgumentException("Unknown type for leftOp: " + leftOp.getClass());
}
}
}
use of soot.jimple.NewMultiArrayExpr in project robovm by robovm.
the class MethodCompiler method doCompile.
protected Function doCompile(ModuleBuilder moduleBuilder, SootMethod method) {
function = createMethodFunction(method);
moduleBuilder.addFunction(function);
this.moduleBuilder = moduleBuilder;
env = function.getParameterRef(0);
trapsAt = new HashMap<Unit, List<Trap>>();
Body body = method.retrieveActiveBody();
NopStmt prependedNop = null;
if (method.isStatic() && !body.getUnits().getFirst().getBoxesPointingToThis().isEmpty()) {
// Fix for issue #1. This prevents an NPE in Soot's ArrayBoundsCheckerAnalysis. The NPE
// occurs for static methods which start with a unit that is the target of some other
// unit. We work around this by inserting a nop statement as the first unit in such
// methods. See http://www.sable.mcgill.ca/listarchives/soot-list/msg01397.html.
Unit insertionPoint = body.getUnits().getFirst();
prependedNop = Jimple.v().newNopStmt();
body.getUnits().getNonPatchingChain().insertBefore(prependedNop, insertionPoint);
}
PackManager.v().getPack("jtp").apply(body);
PackManager.v().getPack("jop").apply(body);
PackManager.v().getPack("jap").apply(body);
if (body.getUnits().getFirst() == prependedNop && prependedNop.getBoxesPointingToThis().isEmpty()) {
// Remove the nop we inserted above to work around the bug in Soot's
// ArrayBoundsCheckerAnalysis which has now been run.
body.getUnits().getNonPatchingChain().removeFirst();
}
PatchingChain<Unit> units = body.getUnits();
Map<Unit, List<Unit>> branchTargets = getBranchTargets(body);
Map<Unit, Integer> trapHandlers = getTrapHandlers(body);
Map<Unit, Integer> selChanges = new HashMap<Unit, Integer>();
int multiANewArrayMaxDims = 0;
Set<Local> locals = new HashSet<Local>();
boolean emitCheckStackOverflow = false;
for (Unit unit : units) {
if (unit instanceof DefinitionStmt) {
DefinitionStmt stmt = (DefinitionStmt) unit;
if (stmt.getLeftOp() instanceof Local) {
Local local = (Local) stmt.getLeftOp();
if (!locals.contains(local)) {
Type type = getLocalType(local.getType());
Alloca alloca = new Alloca(function.newVariable(local.getName(), type), type);
alloca.attach(local);
function.add(alloca);
locals.add(local);
}
}
if (stmt.getRightOp() instanceof NewMultiArrayExpr) {
NewMultiArrayExpr expr = (NewMultiArrayExpr) stmt.getRightOp();
multiANewArrayMaxDims = Math.max(multiANewArrayMaxDims, expr.getSizeCount());
}
if (stmt.getRightOp() instanceof InvokeExpr) {
emitCheckStackOverflow = true;
}
}
if (unit instanceof InvokeStmt) {
emitCheckStackOverflow = true;
}
}
dims = null;
if (multiANewArrayMaxDims > 0) {
dims = function.newVariable("dims", new PointerType(new ArrayType(multiANewArrayMaxDims, I32)));
function.add(new Alloca(dims, new ArrayType(multiANewArrayMaxDims, I32)));
}
if (emitCheckStackOverflow) {
call(CHECK_STACK_OVERFLOW);
}
Value trycatchContext = null;
if (!body.getTraps().isEmpty()) {
List<List<Trap>> recordedTraps = new ArrayList<List<Trap>>();
for (Unit unit : units) {
// Calculate the predecessor units of unit
Set<Unit> incoming = new HashSet<Unit>();
if (units.getFirst() != unit && units.getPredOf(unit).fallsThrough()) {
incoming.add(units.getPredOf(unit));
}
if (branchTargets.keySet().contains(unit)) {
incoming.addAll(branchTargets.get(unit));
}
if (unit == units.getFirst() || trapHandlers.containsKey(unit) || trapsDiffer(unit, incoming)) {
List<Trap> traps = getTrapsAt(unit);
if (traps.isEmpty()) {
selChanges.put(unit, 0);
} else {
int index = recordedTraps.indexOf(traps);
if (index == -1) {
index = recordedTraps.size();
recordedTraps.add(traps);
}
selChanges.put(unit, index + 1);
}
}
}
StructureConstantBuilder landingPadsPtrs = new StructureConstantBuilder();
for (List<Trap> traps : recordedTraps) {
StructureConstantBuilder landingPads = new StructureConstantBuilder();
for (Trap trap : traps) {
SootClass exClass = trap.getException();
StructureConstantBuilder landingPad = new StructureConstantBuilder();
if ("java.lang.Throwable".equals(exClass.getName()) || exClass.isPhantom()) {
landingPad.add(new NullConstant(I8_PTR));
} else {
catches.add(getInternalName(exClass));
if (exClass == sootClass) {
/*
* The class being compiled is an exception class
* with a catch clause which catches itself. We
* cannot reference the info struct directly since
* we don't know the type of it and it hasn't been
* emitted by ClassCompiler yet. Use the internal
* i8* alias instead which ClassCompiler will emit.
* See #1007.
*/
landingPad.add(new AliasRef(Symbols.infoStructSymbol(getInternalName(exClass)) + "_i8ptr", I8_PTR));
} else {
Global g = new Global(Symbols.infoStructSymbol(getInternalName(exClass)), I8_PTR, true);
if (!moduleBuilder.hasSymbol(g.getName())) {
moduleBuilder.addGlobal(g);
}
landingPad.add(g.ref());
}
}
landingPad.add(new IntegerConstant(trapHandlers.get(trap.getHandlerUnit()) + 1));
landingPads.add(landingPad.build());
}
landingPads.add(new StructureConstantBuilder().add(new NullConstant(I8_PTR)).add(new IntegerConstant(0)).build());
Global g = moduleBuilder.newGlobal(landingPads.build(), true);
landingPadsPtrs.add(new ConstantBitcast(g.ref(), I8_PTR));
}
Global g = moduleBuilder.newGlobal(landingPadsPtrs.build(), true);
Variable ctx = function.newVariable(TRYCATCH_CONTEXT_PTR);
Variable bcCtx = function.newVariable(BC_TRYCATCH_CONTEXT_PTR);
function.add(new Alloca(bcCtx, BC_TRYCATCH_CONTEXT));
Variable selPtr = function.newVariable(new PointerType(I32));
function.add(new Getelementptr(selPtr, bcCtx.ref(), 0, 0, 1));
function.add(new Store(new IntegerConstant(0), selPtr.ref()));
Variable bcCtxLandingPadsPtr = function.newVariable(I8_PTR_PTR);
function.add(new Getelementptr(bcCtxLandingPadsPtr, bcCtx.ref(), 0, 1));
function.add(new Store(new ConstantBitcast(g.ref(), I8_PTR), bcCtxLandingPadsPtr.ref()));
function.add(new Bitcast(ctx, bcCtx.ref(), TRYCATCH_CONTEXT_PTR));
trycatchContext = ctx.ref();
Value result = call(RVM_TRYCATCH_ENTER, env, trycatchContext);
Map<IntegerConstant, BasicBlockRef> alt = new TreeMap<IntegerConstant, BasicBlockRef>();
for (Entry<Unit, Integer> entry : trapHandlers.entrySet()) {
alt.put(new IntegerConstant(entry.getValue() + 1), function.newBasicBlockRef(new Label(entry.getKey())));
}
function.add(new Switch(result, function.newBasicBlockRef(new Label(units.getFirst())), alt));
if (!branchTargets.containsKey(units.getFirst())) {
function.newBasicBlock(new Label(units.getFirst()));
}
}
if ("<clinit>".equals(method.getName())) {
initializeClassFields();
}
for (Unit unit : units) {
if (branchTargets.containsKey(unit) || trapHandlers.containsKey(unit)) {
BasicBlock oldBlock = function.getCurrentBasicBlock();
function.newBasicBlock(new Label(unit));
if (oldBlock != null) {
Instruction last = oldBlock.last();
if (last == null || !isTerminator(last)) {
oldBlock.add(new Br(function.newBasicBlockRef(new Label(unit))));
}
}
}
if (selChanges.containsKey(unit)) {
int sel = selChanges.get(unit);
// trycatchContext->sel = sel
Variable selPtr = function.newVariable(new PointerType(I32));
function.add(new Getelementptr(selPtr, trycatchContext, 0, 1)).attach(unit);
function.add(new Store(new IntegerConstant(sel), selPtr.ref())).attach(unit);
}
if (unit instanceof DefinitionStmt) {
assign((DefinitionStmt) unit);
} else if (unit instanceof ReturnStmt) {
if (!body.getTraps().isEmpty()) {
trycatchLeave(function);
}
return_((ReturnStmt) unit);
} else if (unit instanceof ReturnVoidStmt) {
if (!body.getTraps().isEmpty()) {
trycatchLeave(function);
}
returnVoid((ReturnVoidStmt) unit);
} else if (unit instanceof IfStmt) {
if_((IfStmt) unit);
} else if (unit instanceof LookupSwitchStmt) {
lookupSwitch((LookupSwitchStmt) unit);
} else if (unit instanceof TableSwitchStmt) {
tableSwitch((TableSwitchStmt) unit);
} else if (unit instanceof GotoStmt) {
goto_((GotoStmt) unit);
} else if (unit instanceof ThrowStmt) {
throw_((ThrowStmt) unit);
} else if (unit instanceof InvokeStmt) {
invoke((InvokeStmt) unit);
} else if (unit instanceof EnterMonitorStmt) {
enterMonitor((EnterMonitorStmt) unit);
} else if (unit instanceof ExitMonitorStmt) {
exitMonitor((ExitMonitorStmt) unit);
} else if (unit instanceof NopStmt) {
nop((NopStmt) unit);
} else {
throw new IllegalArgumentException("Unknown Unit type: " + unit.getClass());
}
}
if (this.className.equals("java/lang/Object") && "<init>".equals(method.getName())) {
// If it is the object will be registered for finalization.
for (BasicBlock bb : function.getBasicBlocks()) {
if (bb.last() instanceof Ret) {
// Insert a call to register_finalizable() before this ret
Call call = new Call(REGISTER_FINALIZABLE, env, function.getParameterRef(1));
call.attach(bb.last().getAttachment(Unit.class));
bb.insertBefore(bb.last(), call);
}
}
}
return function;
}
use of soot.jimple.NewMultiArrayExpr in project soot by Sable.
the class AsmMethodSource method convertMultiANewArrayInsn.
private void convertMultiANewArrayInsn(MultiANewArrayInsnNode insn) {
StackFrame frame = getFrame(insn);
Operand[] out = frame.out();
Operand opr;
if (out == null) {
ArrayType t = (ArrayType) AsmUtil.toJimpleType(insn.desc);
int dims = insn.dims;
Operand[] sizes = new Operand[dims];
Value[] sizeVals = new Value[dims];
ValueBox[] boxes = new ValueBox[dims];
while (dims-- != 0) {
sizes[dims] = popImmediate();
sizeVals[dims] = sizes[dims].stackOrValue();
}
NewMultiArrayExpr nm = Jimple.v().newNewMultiArrayExpr(t, Arrays.asList(sizeVals));
for (int i = 0; i != boxes.length; i++) {
ValueBox vb = nm.getSizeBox(i);
sizes[i].addBox(vb);
boxes[i] = vb;
}
frame.boxes(boxes);
frame.in(sizes);
opr = new Operand(insn, nm);
frame.out(opr);
} else {
opr = out[0];
int dims = insn.dims;
Operand[] sizes = new Operand[dims];
while (dims-- != 0) sizes[dims] = pop();
frame.mergeIn(sizes);
}
push(opr);
}
use of soot.jimple.NewMultiArrayExpr 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.NewMultiArrayExpr 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