package org.joogie.soot; import org.joogie.GlobalsCache; import org.joogie.util.Log; import org.joogie.util.TranslationHelpers; import soot.Unit; import soot.Value; import soot.jimple.InvokeExpr; import soot.jimple.NewArrayExpr; import soot.jimple.NewExpr; import soot.jimple.NewMultiArrayExpr; import soot.jimple.StringConstant; import boogie.ProgramFactory; import boogie.ast.expression.ArrayAccessExpression; import boogie.ast.expression.Expression; import boogie.ast.expression.IdentifierExpression; public class AssignmentTranslation { public static void translateAssignment(SootStmtSwitch ss, Value lhs, Value rhs, Unit statement) { ProgramFactory pf = GlobalsCache.v().getPf(); SootValueSwitch valueswitch = ss.getValueSwitch(); if (rhs instanceof InvokeExpr) { InvokeExpr ivk = (InvokeExpr) rhs; InvokeTranslation .translateInvokeAssignment(ss, lhs, ivk, statement); return; } valueswitch.isLeftHandSide = true; lhs.apply(valueswitch); valueswitch.isLeftHandSide = false; Expression left = valueswitch.getExpression(); Expression right; if (rhs instanceof NewExpr) { right = ss.createAllocatedVariable(((NewExpr) rhs).getBaseType()); } else if (rhs instanceof NewArrayExpr) { NewArrayExpr nae = (NewArrayExpr) rhs; right = ss.createAllocatedVariable(nae.getType()); nae.getSize().apply(valueswitch); Expression sizeexp = valueswitch.getExpression(); // add the size expression. ss.addStatement(GlobalsCache.v().setArraySizeStatement(right, sizeexp)); } else if (rhs instanceof NewMultiArrayExpr) { NewMultiArrayExpr nmae = (NewMultiArrayExpr) rhs; for (int i = 0; i < nmae.getSizeCount(); i++) { nmae.getSize(i).apply(valueswitch); // Expression sizeexp = valueswitch.getExpression(); // TODO Log.error("Mulit-arrays are not implemented!"); } right = GlobalsCache.v().makeFreshGlobal( SootPrelude.v().getReferenceType(), true, true); } else if (rhs instanceof StringConstant) { StringConstant str = (StringConstant) rhs; // right = stringConstantMap.get(str); right = ss.createAllocatedVariable(rhs.getType()); Expression[] indices = { right }; // assign the size of the string to the appropriate field in the // $stringSizeHeapVariable array. translateAssignment( ss, SootPrelude.v().getStringSizeHeapVariable(), pf.mkArrayStoreExpression(SootPrelude.v() .getStringSizeHeapVariable().getType(), SootPrelude .v().getStringSizeHeapVariable(), indices, pf .mkIntLiteral(Integer.toString(str.value.length())))); } else { rhs.apply(valueswitch); right = valueswitch.getExpression(); } translateAssignment(ss, left, right); } /** * This method creates an assignment. It is used by caseAssignStmt and * caseIdentityStmt * * @param loc * @param left * @param right */ public static void translateAssignment(SootStmtSwitch ss, Expression left, Expression right) { ProgramFactory pf = GlobalsCache.v().getPf(); if (left instanceof IdentifierExpression) { ss.addStatement(pf.mkAssignmentStatement( (IdentifierExpression) left, TranslationHelpers.castBoogieTypes(right, left.getType()))); } else if (left instanceof ArrayAccessExpression) { ArrayAccessExpression aae = (ArrayAccessExpression) left; Expression arraystore = pf.mkArrayStoreExpression(aae.getArray() .getType(), aae.getArray(), aae.getIndices(), right); translateAssignment(ss, aae.getArray(), arraystore); } else { throw new RuntimeException("Unknown LHS type: " + ((left == null) ? "null" : left.getClass())); } } }