Search in sources :

Example 1 with BinopExpr

use of soot.jimple.BinopExpr 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());
        }
    }
}
Also used : Add(org.robovm.compiler.llvm.Add) AndExpr(soot.jimple.AndExpr) New(org.robovm.compiler.trampoline.New) Or(org.robovm.compiler.llvm.Or) Store(org.robovm.compiler.llvm.Store) FloatingPointType(org.robovm.compiler.llvm.FloatingPointType) ArrayType(org.robovm.compiler.llvm.ArrayType) RefLikeType(soot.RefLikeType) GetStatic(org.robovm.compiler.trampoline.GetStatic) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Shl(org.robovm.compiler.llvm.Shl) CastExpr(soot.jimple.CastExpr) PrimType(soot.PrimType) Fsub(org.robovm.compiler.llvm.Fsub) ShlExpr(soot.jimple.ShlExpr) Checkcast(org.robovm.compiler.trampoline.Checkcast) FunctionRef(org.robovm.compiler.llvm.FunctionRef) Fmul(org.robovm.compiler.llvm.Fmul) Sub(org.robovm.compiler.llvm.Sub) GetField(org.robovm.compiler.trampoline.GetField) Load(org.robovm.compiler.llvm.Load) FloatingPointConstant(org.robovm.compiler.llvm.FloatingPointConstant) Mul(org.robovm.compiler.llvm.Mul) XorExpr(soot.jimple.XorExpr) Fptrunc(org.robovm.compiler.llvm.Fptrunc) Local(soot.Local) AddExpr(soot.jimple.AddExpr) Fdiv(org.robovm.compiler.llvm.Fdiv) Zext(org.robovm.compiler.llvm.Zext) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) StaticFieldRef(soot.jimple.StaticFieldRef) NegExpr(soot.jimple.NegExpr) UshrExpr(soot.jimple.UshrExpr) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) GeExpr(soot.jimple.GeExpr) DivExpr(soot.jimple.DivExpr) ConditionExpr(soot.jimple.ConditionExpr) SubExpr(soot.jimple.SubExpr) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) OrExpr(soot.jimple.OrExpr) Expr(soot.jimple.Expr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) LengthExpr(soot.jimple.LengthExpr) ShlExpr(soot.jimple.ShlExpr) NeExpr(soot.jimple.NeExpr) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) CmpExpr(soot.jimple.CmpExpr) MulExpr(soot.jimple.MulExpr) BinopExpr(soot.jimple.BinopExpr) LtExpr(soot.jimple.LtExpr) ShrExpr(soot.jimple.ShrExpr) CmpgExpr(soot.jimple.CmpgExpr) EqExpr(soot.jimple.EqExpr) NewArrayExpr(soot.jimple.NewArrayExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) AndExpr(soot.jimple.AndExpr) LeExpr(soot.jimple.LeExpr) CastExpr(soot.jimple.CastExpr) InvokeExpr(soot.jimple.InvokeExpr) NewExpr(soot.jimple.NewExpr) CmplExpr(soot.jimple.CmplExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) RemExpr(soot.jimple.RemExpr) XorExpr(soot.jimple.XorExpr) AddExpr(soot.jimple.AddExpr) GtExpr(soot.jimple.GtExpr) Bitcast(org.robovm.compiler.llvm.Bitcast) ConstantBitcast(org.robovm.compiler.llvm.ConstantBitcast) NewArrayExpr(soot.jimple.NewArrayExpr) And(org.robovm.compiler.llvm.And) CmpExpr(soot.jimple.CmpExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) Value(org.robovm.compiler.llvm.Value) NewExpr(soot.jimple.NewExpr) Fadd(org.robovm.compiler.llvm.Fadd) Xor(org.robovm.compiler.llvm.Xor) NullType(soot.NullType) CmplExpr(soot.jimple.CmplExpr) BinopExpr(soot.jimple.BinopExpr) MulExpr(soot.jimple.MulExpr) GlobalRef(org.robovm.compiler.llvm.GlobalRef) VariableRef(org.robovm.compiler.llvm.VariableRef) Variable(org.robovm.compiler.llvm.Variable) Ashr(org.robovm.compiler.llvm.Ashr) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) Sext(org.robovm.compiler.llvm.Sext) NegExpr(soot.jimple.NegExpr) PointerType(org.robovm.compiler.llvm.PointerType) Getelementptr(org.robovm.compiler.llvm.Getelementptr) Multianewarray(org.robovm.compiler.trampoline.Multianewarray) UshrExpr(soot.jimple.UshrExpr) ArrayRef(soot.jimple.ArrayRef) Lshr(org.robovm.compiler.llvm.Lshr) InstanceFieldRef(soot.jimple.InstanceFieldRef) Trunc(org.robovm.compiler.llvm.Trunc) ConstantTrunc(org.robovm.compiler.llvm.ConstantTrunc) Instanceof(org.robovm.compiler.trampoline.Instanceof) Sitofp(org.robovm.compiler.llvm.Sitofp) PutField(org.robovm.compiler.trampoline.PutField) Call(org.robovm.compiler.llvm.Call) Trampoline(org.robovm.compiler.trampoline.Trampoline) LengthExpr(soot.jimple.LengthExpr) Immediate(soot.Immediate) FunctionType(org.robovm.compiler.llvm.FunctionType) SubExpr(soot.jimple.SubExpr) Anewarray(org.robovm.compiler.trampoline.Anewarray) PutStatic(org.robovm.compiler.trampoline.PutStatic) IntegerType(org.robovm.compiler.llvm.IntegerType) FloatingPointType(org.robovm.compiler.llvm.FloatingPointType) IntegerType(org.robovm.compiler.llvm.IntegerType) PointerType(org.robovm.compiler.llvm.PointerType) NullType(soot.NullType) FunctionType(org.robovm.compiler.llvm.FunctionType) ArrayType(org.robovm.compiler.llvm.ArrayType) CharType(soot.CharType) RefLikeType(soot.RefLikeType) Type(org.robovm.compiler.llvm.Type) PrimType(soot.PrimType) DivExpr(soot.jimple.DivExpr) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) CmpgExpr(soot.jimple.CmpgExpr) Fpext(org.robovm.compiler.llvm.Fpext) Icmp(org.robovm.compiler.llvm.Icmp)

Example 2 with BinopExpr

use of soot.jimple.BinopExpr 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);
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) DivExpr(soot.jimple.DivExpr) RefType(soot.RefType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) ArrayType(soot.ArrayType) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 3 with BinopExpr

use of soot.jimple.BinopExpr 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);
    }
}
Also used : LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) FloatConstant(soot.jimple.FloatConstant) Local(soot.Local) NullConstant(soot.jimple.NullConstant) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 4 with BinopExpr

use of soot.jimple.BinopExpr 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);
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) IntegerType(soot.IntegerType) Type(soot.Type) NullType(soot.NullType) ArrayType(soot.ArrayType) IntegerType(soot.IntegerType) DivExpr(soot.jimple.DivExpr) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) NullType(soot.NullType) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 5 with BinopExpr

use of soot.jimple.BinopExpr in project soot by Sable.

the class ArrayIndexLivenessAnalysis method getGenAndKillSetForDefnStmt.

private void getGenAndKillSetForDefnStmt(DefinitionStmt asstmt, HashMap<Stmt, HashSet<Value>> absgen, HashSet<Object> genset, HashSet<Value> absgenset, HashSet<Value> killset, HashSet<Value> condset) {
    /* kill left hand side */
    Value lhs = asstmt.getLeftOp();
    Value rhs = asstmt.getRightOp();
    boolean killarrayrelated = false;
    boolean killallarrayref = false;
    if (fieldin) {
        if (lhs instanceof Local) {
            HashSet<Value> related = localToFieldRef.get(lhs);
            if (related != null)
                killset.addAll(related);
        } else if (lhs instanceof StaticFieldRef) {
            killset.add(lhs);
            condset.add(lhs);
        } else if (lhs instanceof InstanceFieldRef) {
            SootField field = ((InstanceFieldRef) lhs).getField();
            HashSet<Value> related = fieldToFieldRef.get(field);
            if (related != null)
                killset.addAll(related);
            condset.add(lhs);
        }
        if (asstmt.containsInvokeExpr()) {
            /*
                Value expr = asstmt.getInvokeExpr();
                List parameters = ((InvokeExpr)expr).getArgs();

                // add the method invocation
                boolean killall = false;
                if (expr instanceof InstanceInvokeExpr)
                    killall = true;
                else
                {
                    for (int i=0; i<parameters.size(); i++)
                    {
                    Value para = (Value)parameters.get(i);
                    if (para.getType() instanceof RefType)
                    {
                        killall = true;
                        break;
                    }
                    }
                }
    
                if (killall)
                {
                    killset.addAll(allInstFieldRefs);
                }   
                */
            killset.addAll(allFieldRefs);
        }
    }
    if (arrayin) {
        // a = ... or i = ...
        if (lhs instanceof Local) {
            killarrayrelated = true;
        } else // a[i] = ...
        if (lhs instanceof ArrayRef) {
            killallarrayref = true;
            condset.add(lhs);
        }
        // invokeexpr kills all array references.
        if (asstmt.containsInvokeExpr()) {
            killallarrayref = true;
        }
    }
    if (csin) {
        HashSet<Value> exprs = localToExpr.get(lhs);
        if (exprs != null)
            killset.addAll(exprs);
        if (rhs instanceof BinopExpr) {
            Value op1 = ((BinopExpr) rhs).getOp1();
            Value op2 = ((BinopExpr) rhs).getOp2();
            if (rhs instanceof AddExpr) {
                if ((op1 instanceof Local) && (op2 instanceof Local))
                    genset.add(rhs);
            } else if (rhs instanceof MulExpr) {
                if ((op1 instanceof Local) || (op2 instanceof Local))
                    genset.add(rhs);
            } else if (rhs instanceof SubExpr) {
                if (op2 instanceof Local)
                    genset.add(rhs);
            }
        }
    }
    if ((lhs instanceof Local) && (fullSet.contains(lhs))) {
        killset.add(lhs);
        /* speculatively add lhs as live condition. */
        condset.add(lhs);
    } else if (lhs instanceof ArrayRef) {
        /* a[i] generate a and i. */
        Value base = ((ArrayRef) lhs).getBase();
        Value index = ((ArrayRef) lhs).getIndex();
        absgenset.add(base);
        if (index instanceof Local) {
            absgenset.add(index);
        }
    }
    if (rhs instanceof Local) {
        /*
              if (lhs instanceof Local && fullSet.contains(rhs))
              genset.add(rhs);
            */
        if (fullSet.contains(rhs))
            genset.add(rhs);
    /*
              if (fieldin && (lhs instanceof FieldRef))
              genset.add(rhs);
            */
    } else if (rhs instanceof FieldRef) {
        if (fieldin)
            genset.add(rhs);
    } else if (rhs instanceof ArrayRef) {
        /* lhs=a[i]. */
        Value base = ((ArrayRef) rhs).getBase();
        Value index = ((ArrayRef) rhs).getIndex();
        absgenset.add(base);
        if (index instanceof Local) {
            absgenset.add(index);
        }
        if (arrayin) {
            genset.add(rhs);
            if (rectarray)
                genset.add(Array2ndDimensionSymbol.v(base));
        }
    } else if (rhs instanceof NewArrayExpr) {
        /* a = new A[i]; */
        Value size = ((NewArrayExpr) rhs).getSize();
        if (size instanceof Local)
            genset.add(size);
    } else if (rhs instanceof NewMultiArrayExpr) {
        /* a = new A[i][]...;*/
        /* More precisely, we should track other dimensions. */
        List sizes = ((NewMultiArrayExpr) rhs).getSizes();
        Iterator sizeIt = sizes.iterator();
        while (sizeIt.hasNext()) {
            Value size = (Value) sizeIt.next();
            if (size instanceof Local)
                genset.add(size);
        }
    } else if (rhs instanceof LengthExpr) {
        /* lhs = lengthof rhs */
        Value op = ((LengthExpr) rhs).getOp();
        genset.add(op);
    } else if (rhs instanceof JAddExpr) {
        /* lhs = rhs+c, lhs=c+rhs */
        Value op1 = ((JAddExpr) rhs).getOp1();
        Value op2 = ((JAddExpr) rhs).getOp2();
        if ((op1 instanceof IntConstant) && (op2 instanceof Local)) {
            genset.add(op2);
        } else if ((op2 instanceof IntConstant) && (op1 instanceof Local)) {
            genset.add(op1);
        }
    } else if (rhs instanceof JSubExpr) {
        Value op1 = ((JSubExpr) rhs).getOp1();
        Value op2 = ((JSubExpr) rhs).getOp2();
        if ((op1 instanceof Local) && (op2 instanceof IntConstant)) {
            genset.add(op1);
        }
    }
    if (arrayin) {
        if (killarrayrelated)
            killArrayRelated.put(asstmt, lhs);
        if (killallarrayref)
            killAllArrayRef.put(asstmt, new Boolean(true));
    }
}
Also used : MulExpr(soot.jimple.MulExpr) JSubExpr(soot.jimple.internal.JSubExpr) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) LengthExpr(soot.jimple.LengthExpr) JSubExpr(soot.jimple.internal.JSubExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) JAddExpr(soot.jimple.internal.JAddExpr) AddExpr(soot.jimple.AddExpr) StaticFieldRef(soot.jimple.StaticFieldRef) ArrayRef(soot.jimple.ArrayRef) NewArrayExpr(soot.jimple.NewArrayExpr) Value(soot.Value) InstanceFieldRef(soot.jimple.InstanceFieldRef) Iterator(java.util.Iterator) IntConstant(soot.jimple.IntConstant) SootField(soot.SootField) ArrayList(java.util.ArrayList) List(java.util.List) JAddExpr(soot.jimple.internal.JAddExpr) BinopExpr(soot.jimple.BinopExpr)

Aggregations

BinopExpr (soot.jimple.BinopExpr)26 Value (soot.Value)21 Local (soot.Local)19 ArrayRef (soot.jimple.ArrayRef)12 CastExpr (soot.jimple.CastExpr)11 NewArrayExpr (soot.jimple.NewArrayExpr)11 NullConstant (soot.jimple.NullConstant)11 Type (soot.Type)10 InstanceFieldRef (soot.jimple.InstanceFieldRef)10 IntConstant (soot.jimple.IntConstant)10 InvokeExpr (soot.jimple.InvokeExpr)10 LengthExpr (soot.jimple.LengthExpr)9 IfStmt (soot.jimple.IfStmt)8 LongConstant (soot.jimple.LongConstant)8 StringConstant (soot.jimple.StringConstant)8 Unit (soot.Unit)7 AssignStmt (soot.jimple.AssignStmt)7 FieldRef (soot.jimple.FieldRef)7 NewExpr (soot.jimple.NewExpr)7 NewMultiArrayExpr (soot.jimple.NewMultiArrayExpr)7