Search in sources :

Example 1 with NullType

use of soot.NullType 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 NullType

use of soot.NullType in project soot by Sable.

the class GroupIntPair method emitInst.

void emitInst(Inst inst) {
    LineNumberTag lnTag = (LineNumberTag) inst.getTag("LineNumberTag");
    if (lnTag != null)
        emit(".line " + lnTag.getLineNumber());
    inst.apply(new InstSwitch() {

        @Override
        public void caseReturnVoidInst(ReturnVoidInst i) {
            emit("return");
        }

        @Override
        public void caseReturnInst(ReturnInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid return type " + t.toString());
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dreturn");
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("freturn");
                }

                @Override
                public void caseIntType(IntType t) {
                    emit("ireturn");
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("ireturn");
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("ireturn");
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("ireturn");
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("ireturn");
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lreturn");
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("areturn");
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("areturn");
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("areturn");
                }
            });
        }

        @Override
        public void caseNopInst(NopInst i) {
            emit("nop");
        }

        @Override
        public void caseEnterMonitorInst(EnterMonitorInst i) {
            emit("monitorenter");
        }

        @Override
        public void casePopInst(PopInst i) {
            if (i.getWordCount() == 2) {
                emit("pop2");
            } else
                emit("pop");
        }

        @Override
        public void caseExitMonitorInst(ExitMonitorInst i) {
            emit("monitorexit");
        }

        @Override
        public void caseGotoInst(GotoInst i) {
            emit("goto " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseJSRInst(JSRInst i) {
            emit("jsr " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void casePushInst(PushInst i) {
            if (i.getConstant() instanceof IntConstant) {
                IntConstant v = (IntConstant) (i.getConstant());
                if (v.value == -1)
                    emit("iconst_m1");
                else if (v.value >= 0 && v.value <= 5)
                    emit("iconst_" + v.value);
                else if (v.value >= Byte.MIN_VALUE && v.value <= Byte.MAX_VALUE)
                    emit("bipush " + v.value);
                else if (v.value >= Short.MIN_VALUE && v.value <= Short.MAX_VALUE)
                    emit("sipush " + v.value);
                else
                    emit("ldc " + v.toString());
            } else if (i.getConstant() instanceof StringConstant) {
                emit("ldc " + i.getConstant().toString());
            } else if (i.getConstant() instanceof ClassConstant) {
                emit("ldc_w " + ((ClassConstant) i.getConstant()).getValue());
            } else if (i.getConstant() instanceof DoubleConstant) {
                DoubleConstant v = (DoubleConstant) (i.getConstant());
                if ((v.value == 0) && ((1.0 / v.value) > 0.0))
                    emit("dconst_0");
                else if (v.value == 1)
                    emit("dconst_1");
                else {
                    String s = doubleToString(v);
                    emit("ldc2_w " + s);
                }
            } else if (i.getConstant() instanceof FloatConstant) {
                FloatConstant v = (FloatConstant) (i.getConstant());
                if ((v.value == 0) && ((1.0f / v.value) > 1.0f))
                    emit("fconst_0");
                else if (v.value == 1)
                    emit("fconst_1");
                else if (v.value == 2)
                    emit("fconst_2");
                else {
                    String s = floatToString(v);
                    emit("ldc " + s);
                }
            } else if (i.getConstant() instanceof LongConstant) {
                LongConstant v = (LongConstant) (i.getConstant());
                if (v.value == 0)
                    emit("lconst_0");
                else if (v.value == 1)
                    emit("lconst_1");
                else
                    emit("ldc2_w " + v.toString());
            } else if (i.getConstant() instanceof NullConstant) {
                emit("aconst_null");
            } else if (i.getConstant() instanceof MethodHandle) {
                throw new RuntimeException("MethodHandle constants not supported by Jasmin. Please use -asm-backend.");
            } else
                throw new RuntimeException("unsupported opcode");
        }

        @Override
        public void caseIdentityInst(IdentityInst i) {
            if (i.getRightOp() instanceof CaughtExceptionRef && i.getLeftOp() instanceof Local) {
                int slot = localToSlot.get(i.getLeftOp()).intValue();
                if (slot >= 0 && slot <= 3)
                    emit("astore_" + slot);
                else
                    emit("astore " + slot);
            }
        }

        @Override
        public void caseStoreInst(StoreInst i) {
            final int slot = localToSlot.get(i.getLocal()).intValue();
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("astore_" + slot);
                    else
                        emit("astore " + slot);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("dstore_" + slot);
                    else
                        emit("dstore " + slot);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("fstore_" + slot);
                    else
                        emit("fstore " + slot);
                }

                @Override
                public void caseIntType(IntType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseByteType(ByteType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseShortType(ShortType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseCharType(CharType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("istore_" + slot);
                    else
                        emit("istore " + slot);
                }

                @Override
                public void caseLongType(LongType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("lstore_" + slot);
                    else
                        emit("lstore " + slot);
                }

                @Override
                public void caseRefType(RefType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("astore_" + slot);
                    else
                        emit("astore " + slot);
                }

                @Override
                public void caseStmtAddressType(StmtAddressType t) {
                    isNextGotoAJsr = true;
                    returnAddressSlot = slot;
                /*
						 * if ( slot >= 0 && slot <= 3) emit("astore_" + slot,
						 * ); else emit("astore " + slot, );
						 */
                }

                @Override
                public void caseNullType(NullType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("astore_" + slot);
                    else
                        emit("astore " + slot);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid local type:" + t);
                }
            });
        }

        @Override
        public void caseLoadInst(LoadInst i) {
            final int slot = localToSlot.get(i.getLocal()).intValue();
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("aload_" + slot);
                    else
                        emit("aload " + slot);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid local type to load" + t);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("dload_" + slot);
                    else
                        emit("dload " + slot);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("fload_" + slot);
                    else
                        emit("fload " + slot);
                }

                @Override
                public void caseIntType(IntType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseByteType(ByteType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseShortType(ShortType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseCharType(CharType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("iload_" + slot);
                    else
                        emit("iload " + slot);
                }

                @Override
                public void caseLongType(LongType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("lload_" + slot);
                    else
                        emit("lload " + slot);
                }

                @Override
                public void caseRefType(RefType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("aload_" + slot);
                    else
                        emit("aload " + slot);
                }

                @Override
                public void caseNullType(NullType t) {
                    if (slot >= 0 && slot <= 3)
                        emit("aload_" + slot);
                    else
                        emit("aload " + slot);
                }
            });
        }

        @Override
        public void caseArrayWriteInst(ArrayWriteInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("aastore");
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dastore");
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fastore");
                }

                @Override
                public void caseIntType(IntType t) {
                    emit("iastore");
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lastore");
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("aastore");
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("bastore");
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("bastore");
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("castore");
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("sastore");
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid type: " + t);
                }
            });
        }

        @Override
        public void caseArrayReadInst(ArrayReadInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseArrayType(ArrayType ty) {
                    emit("aaload");
                }

                @Override
                public void caseBooleanType(BooleanType ty) {
                    emit("baload");
                }

                @Override
                public void caseByteType(ByteType ty) {
                    emit("baload");
                }

                @Override
                public void caseCharType(CharType ty) {
                    emit("caload");
                }

                @Override
                public void defaultCase(Type ty) {
                    throw new RuntimeException("invalid base type");
                }

                @Override
                public void caseDoubleType(DoubleType ty) {
                    emit("daload");
                }

                @Override
                public void caseFloatType(FloatType ty) {
                    emit("faload");
                }

                @Override
                public void caseIntType(IntType ty) {
                    emit("iaload");
                }

                @Override
                public void caseLongType(LongType ty) {
                    emit("laload");
                }

                @Override
                public void caseNullType(NullType ty) {
                    emit("aaload");
                }

                @Override
                public void caseRefType(RefType ty) {
                    emit("aaload");
                }

                @Override
                public void caseShortType(ShortType ty) {
                    emit("saload");
                }
            });
        }

        @Override
        public void caseIfNullInst(IfNullInst i) {
            emit("ifnull " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfNonNullInst(IfNonNullInst i) {
            emit("ifnonnull " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfEqInst(IfEqInst i) {
            emit("ifeq " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfNeInst(IfNeInst i) {
            emit("ifne " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfGtInst(IfGtInst i) {
            emit("ifgt " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfGeInst(IfGeInst i) {
            emit("ifge " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfLtInst(IfLtInst i) {
            emit("iflt " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfLeInst(IfLeInst i) {
            emit("ifle " + unitToLabel.get(i.getTarget()));
        }

        @Override
        public void caseIfCmpEqInst(final IfCmpEqInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpNeInst(final IfCmpNeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpne " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpGtInst(final IfCmpGtInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpGeInst(final IfCmpGeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmpge " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpLtInst(final IfCmpLtInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("iflt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("iflt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("iflt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmplt " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseIfCmpLeInst(final IfCmpLeInst i) {
            i.getOpType().apply(new TypeSwitch() {

                @Override
                public void caseIntType(IntType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseShortType(ShortType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseCharType(CharType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseByteType(ByteType t) {
                    emit("if_icmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("dcmpg");
                    emit("ifle " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("lcmp");
                    emit("ifle " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("fcmpg");
                    emit("ifle " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseArrayType(ArrayType t) {
                    emit("if_acmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseRefType(RefType t) {
                    emit("if_acmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void caseNullType(NullType t) {
                    emit("if_acmple " + unitToLabel.get(i.getTarget()));
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("invalid type");
                }
            });
        }

        @Override
        public void caseStaticGetInst(StaticGetInst i) {
            SootFieldRef field = i.getFieldRef();
            emit("getstatic " + slashify(field.declaringClass().getName()) + "/" + field.name() + " " + jasminDescriptorOf(field.type()));
        }

        @Override
        public void caseStaticPutInst(StaticPutInst i) {
            emit("putstatic " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
        }

        @Override
        public void caseFieldGetInst(FieldGetInst i) {
            emit("getfield " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
        }

        @Override
        public void caseFieldPutInst(FieldPutInst i) {
            emit("putfield " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
        }

        @Override
        public void caseInstanceCastInst(InstanceCastInst i) {
            Type castType = i.getCastType();
            if (castType instanceof RefType)
                emit("checkcast " + slashify(((RefType) castType).getClassName()));
            else if (castType instanceof ArrayType)
                emit("checkcast " + jasminDescriptorOf(castType));
        }

        @Override
        public void caseInstanceOfInst(InstanceOfInst i) {
            Type checkType = i.getCheckType();
            if (checkType instanceof RefType)
                emit("instanceof " + slashify(checkType.toString()));
            else if (checkType instanceof ArrayType)
                emit("instanceof " + jasminDescriptorOf(checkType));
        }

        @Override
        public void caseNewInst(NewInst i) {
            emit("new " + slashify(i.getBaseType().getClassName()));
        }

        @Override
        public void casePrimitiveCastInst(PrimitiveCastInst i) {
            emit(i.toString());
        }

        @Override
        public void caseDynamicInvokeInst(DynamicInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            SootMethodRef bsm = i.getBootstrapMethodRef();
            String bsmArgString = "";
            for (Iterator<Value> iterator = i.getBootstrapArgs().iterator(); iterator.hasNext(); ) {
                Value val = iterator.next();
                bsmArgString += "(" + jasminDescriptorOf(val.getType()) + ")";
                bsmArgString += escape(val.toString());
                if (iterator.hasNext())
                    bsmArgString += ",";
            }
            emit("invokedynamic \"" + m.name() + "\" " + jasminDescriptorOf(m) + " " + slashify(bsm.declaringClass().getName()) + "/" + bsm.name() + jasminDescriptorOf(bsm) + "(" + bsmArgString + ")");
        }

        private String escape(String bsmArgString) {
            return bsmArgString.replace(",", "\\comma").replace(" ", "\\blank").replace("\t", "\\tab").replace("\n", "\\newline");
        }

        @Override
        public void caseStaticInvokeInst(StaticInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokestatic " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
        }

        @Override
        public void caseVirtualInvokeInst(VirtualInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokevirtual " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
        }

        @Override
        public void caseInterfaceInvokeInst(InterfaceInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokeinterface " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m) + " " + (argCountOf(m) + 1));
        }

        @Override
        public void caseSpecialInvokeInst(SpecialInvokeInst i) {
            SootMethodRef m = i.getMethodRef();
            emit("invokespecial " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
        }

        @Override
        public void caseThrowInst(ThrowInst i) {
            emit("athrow");
        }

        @Override
        public void caseCmpInst(CmpInst i) {
            emit("lcmp");
        }

        @Override
        public void caseCmplInst(CmplInst i) {
            if (i.getOpType().equals(FloatType.v()))
                emit("fcmpl");
            else
                emit("dcmpl");
        }

        @Override
        public void caseCmpgInst(CmpgInst i) {
            if (i.getOpType().equals(FloatType.v()))
                emit("fcmpg");
            else
                emit("dcmpg");
        }

        private void emitOpTypeInst(final String s, final OpTypeArgInst i) {
            i.getOpType().apply(new TypeSwitch() {

                private void handleIntCase() {
                    emit("i" + s);
                }

                @Override
                public void caseIntType(IntType t) {
                    handleIntCase();
                }

                @Override
                public void caseBooleanType(BooleanType t) {
                    handleIntCase();
                }

                @Override
                public void caseShortType(ShortType t) {
                    handleIntCase();
                }

                @Override
                public void caseCharType(CharType t) {
                    handleIntCase();
                }

                @Override
                public void caseByteType(ByteType t) {
                    handleIntCase();
                }

                @Override
                public void caseLongType(LongType t) {
                    emit("l" + s);
                }

                @Override
                public void caseDoubleType(DoubleType t) {
                    emit("d" + s);
                }

                @Override
                public void caseFloatType(FloatType t) {
                    emit("f" + s);
                }

                @Override
                public void defaultCase(Type t) {
                    throw new RuntimeException("Invalid argument type for div");
                }
            });
        }

        @Override
        public void caseAddInst(AddInst i) {
            emitOpTypeInst("add", i);
        }

        @Override
        public void caseDivInst(DivInst i) {
            emitOpTypeInst("div", i);
        }

        @Override
        public void caseSubInst(SubInst i) {
            emitOpTypeInst("sub", i);
        }

        @Override
        public void caseMulInst(MulInst i) {
            emitOpTypeInst("mul", i);
        }

        @Override
        public void caseRemInst(RemInst i) {
            emitOpTypeInst("rem", i);
        }

        @Override
        public void caseShlInst(ShlInst i) {
            emitOpTypeInst("shl", i);
        }

        @Override
        public void caseAndInst(AndInst i) {
            emitOpTypeInst("and", i);
        }

        @Override
        public void caseOrInst(OrInst i) {
            emitOpTypeInst("or", i);
        }

        @Override
        public void caseXorInst(XorInst i) {
            emitOpTypeInst("xor", i);
        }

        @Override
        public void caseShrInst(ShrInst i) {
            emitOpTypeInst("shr", i);
        }

        @Override
        public void caseUshrInst(UshrInst i) {
            emitOpTypeInst("ushr", i);
        }

        @Override
        public void caseIncInst(IncInst i) {
            if (i.getUseBoxes().get(0).getValue() != i.getDefBoxes().get(0).getValue())
                throw new RuntimeException("iinc def and use boxes don't match");
            emit("iinc " + localToSlot.get(i.getLocal()) + " " + i.getConstant());
        }

        @Override
        public void caseArrayLengthInst(ArrayLengthInst i) {
            emit("arraylength");
        }

        @Override
        public void caseNegInst(NegInst i) {
            emitOpTypeInst("neg", i);
        }

        @Override
        public void caseNewArrayInst(NewArrayInst i) {
            if (i.getBaseType() instanceof RefType)
                emit("anewarray " + slashify(((RefType) i.getBaseType()).getClassName()));
            else if (i.getBaseType() instanceof ArrayType)
                emit("anewarray " + jasminDescriptorOf(i.getBaseType()));
            else
                emit("newarray " + i.getBaseType().toString());
        }

        @Override
        public void caseNewMultiArrayInst(NewMultiArrayInst i) {
            emit("multianewarray " + jasminDescriptorOf(i.getBaseType()) + " " + i.getDimensionCount());
        }

        @Override
        public void caseLookupSwitchInst(LookupSwitchInst i) {
            emit("lookupswitch");
            List<IntConstant> lookupValues = i.getLookupValues();
            List<Unit> targets = i.getTargets();
            for (int j = 0; j < lookupValues.size(); j++) emit("  " + lookupValues.get(j) + " : " + unitToLabel.get(targets.get(j)));
            emit("  default : " + unitToLabel.get(i.getDefaultTarget()));
        }

        @Override
        public void caseTableSwitchInst(TableSwitchInst i) {
            emit("tableswitch " + i.getLowIndex() + " ; high = " + i.getHighIndex());
            List<Unit> targets = i.getTargets();
            for (int j = 0; j < targets.size(); j++) emit("  " + unitToLabel.get(targets.get(j)));
            emit("default : " + unitToLabel.get(i.getDefaultTarget()));
        }

        private boolean isDwordType(Type t) {
            return t instanceof LongType || t instanceof DoubleType || t instanceof DoubleWordType;
        }

        @Override
        public void caseDup1Inst(Dup1Inst i) {
            Type firstOpType = i.getOp1Type();
            if (isDwordType(firstOpType))
                // (form 2)
                emit("dup2");
            else
                emit("dup");
        }

        @Override
        public void caseDup2Inst(Dup2Inst i) {
            Type firstOpType = i.getOp1Type();
            Type secondOpType = i.getOp2Type();
            // Use a pair of insts to simulate them.
            if (isDwordType(firstOpType)) {
                // (form 2)
                emit("dup2");
                if (isDwordType(secondOpType)) {
                    // (form 2 -- by simulation)
                    emit("dup2");
                } else
                    // also a simulation
                    emit("dup");
            } else if (isDwordType(secondOpType)) {
                if (isDwordType(firstOpType)) {
                    // (form 2)
                    emit("dup2");
                } else
                    emit("dup");
                // (form 2 -- complete the simulation)
                emit("dup2");
            } else {
                // form 1
                emit("dup2");
            }
        }

        @Override
        public void caseDup1_x1Inst(Dup1_x1Inst i) {
            Type opType = i.getOp1Type();
            Type underType = i.getUnder1Type();
            if (isDwordType(opType)) {
                if (isDwordType(underType)) {
                    // (form 4)
                    emit("dup2_x2");
                } else
                    // (form 2)
                    emit("dup2_x1");
            } else {
                if (isDwordType(underType))
                    // (form 2)
                    emit("dup_x2");
                else
                    // (only one form)
                    emit("dup_x1");
            }
        }

        @Override
        public void caseDup1_x2Inst(Dup1_x2Inst i) {
            Type opType = i.getOp1Type();
            Type under1Type = i.getUnder1Type();
            Type under2Type = i.getUnder2Type();
            if (isDwordType(opType)) {
                if (!isDwordType(under1Type) && !isDwordType(under2Type))
                    // (form 2)
                    emit("dup2_x2");
                else
                    throw new RuntimeException("magic not implemented yet");
            } else {
                if (isDwordType(under1Type) || isDwordType(under2Type))
                    throw new RuntimeException("magic not implemented yet");
            }
            // (form 1)
            emit("dup_x2");
        }

        @Override
        public void caseDup2_x1Inst(Dup2_x1Inst i) {
            Type op1Type = i.getOp1Type();
            Type op2Type = i.getOp2Type();
            Type under1Type = i.getUnder1Type();
            /*
				 * From VM Spec: cat1 = category 1 (word type) cat2 = category 2
				 * (doubleword)
				 * 
				 * Form 1: [..., cat1_value3, cat1_value2, cat1_value1]->[...,
				 * cat1_value2, cat1_value1, cat1_value3, cat1_value2,
				 * cat1_value1] Form 2: [..., cat1_value2, cat2_value1]->[...,
				 * cat2_value1, cat1_value2, cat2_value1]
				 */
            if (isDwordType(under1Type)) {
                if (!isDwordType(op1Type) && !isDwordType(op2Type))
                    throw new RuntimeException("magic not implemented yet");
                else
                    // (form 3)
                    emit("dup2_x2");
            } else {
                if ((isDwordType(op1Type) && op2Type != null) || isDwordType(op2Type))
                    throw new RuntimeException("magic not implemented yet");
            }
            // (form 1)
            emit("dup2_x1");
        }

        @Override
        public void caseDup2_x2Inst(Dup2_x2Inst i) {
            Type op1Type = i.getOp1Type();
            Type op2Type = i.getOp2Type();
            Type under1Type = i.getUnder1Type();
            Type under2Type = i.getUnder2Type();
            // 07-20-2006 Michael Batchelder
            // NOW handling all types of dup2_x2
            /*
				 * From VM Spec: cat1 = category 1 (word type) cat2 = category 2
				 * (doubleword) Form 1: [..., cat1_value4, cat1_value3,
				 * cat1_value2, cat1_value1]->[..., cat1_value2, cat1_value1,
				 * cat1_value4, cat1_value3, cat1_value2, cat1_value1] Form 2:
				 * [..., cat1_value3, cat1_value2, cat2_value1]->[ ...,
				 * cat2_value1, cat1_value3, cat1_value2, cat2_value1] Form 3:
				 * [..., cat2_value3, cat1_value2, cat1_value1]->[...,
				 * cat1_value2, cat1_value1, cat2_value3, cat1_value2,
				 * cat1_value1] Form 4: [..., cat2_value2, cat2_value1]->[...,
				 * cat2_value1, cat2_value2, cat2_value1]
				 */
            boolean malformed = true;
            if (isDwordType(op1Type)) {
                if (op2Type == null && under1Type != null)
                    if ((under2Type == null && isDwordType(under1Type)) || (!isDwordType(under1Type) && under2Type != null && !isDwordType(under2Type)))
                        malformed = false;
            } else if (op1Type != null && op2Type != null && !isDwordType(op2Type)) {
                if ((under2Type == null && isDwordType(under1Type)) || (under1Type != null && !isDwordType(under1Type) && under2Type != null && !isDwordType(under2Type)))
                    malformed = false;
            }
            if (malformed)
                throw new RuntimeException("magic not implemented yet");
            // (form 1)
            emit("dup2_x2");
        }

        @Override
        public void caseSwapInst(SwapInst i) {
            emit("swap");
        }
    });
}
Also used : TypeSwitch(soot.TypeSwitch) ByteType(soot.ByteType) FloatType(soot.FloatType) LineNumberTag(soot.tagkit.LineNumberTag) ShortType(soot.ShortType) Local(soot.Local) IntType(soot.IntType) BooleanType(soot.BooleanType) RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) ShortType(soot.ShortType) CharType(soot.CharType) LongType(soot.LongType) NullType(soot.NullType) StmtAddressType(soot.StmtAddressType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) ArrayType(soot.ArrayType) Type(soot.Type) StmtAddressType(soot.StmtAddressType) ArrayType(soot.ArrayType) RefType(soot.RefType) List(java.util.List) SootFieldRef(soot.SootFieldRef) Value(soot.Value) CharType(soot.CharType) NullType(soot.NullType) LongType(soot.LongType) Iterator(java.util.Iterator) SootMethodRef(soot.SootMethodRef) DoubleType(soot.DoubleType)

Example 3 with NullType

use of soot.NullType in project soot by Sable.

the class TypeAssigner method replaceNullType.

/**
 * Replace statements using locals with null_type type and that would
 * throw a NullPointerException at runtime by a set of instructions
 * throwing a NullPointerException.
 *
 * This is done to remove locals with null_type type.
 *
 * @param b
 */
private void replaceNullType(Body b) {
    List<Local> localsToRemove = new ArrayList<Local>();
    boolean hasNullType = false;
    // check if any local has null_type
    for (Local l : b.getLocals()) {
        if (l.getType() instanceof NullType) {
            localsToRemove.add(l);
            hasNullType = true;
        }
    }
    // No local with null_type
    if (!hasNullType)
        return;
    // force to propagate null constants
    Map<String, String> opts = PhaseOptions.v().getPhaseOptions("jop.cpf");
    if (!opts.containsKey("enabled") || !opts.get("enabled").equals("true")) {
        logger.warn("Cannot run TypeAssigner.replaceNullType(Body). Try to enable jop.cfg.");
        return;
    }
    ConstantPropagatorAndFolder.v().transform(b);
    List<Unit> unitToReplaceByException = new ArrayList<Unit>();
    for (Unit u : b.getUnits()) {
        for (ValueBox vb : u.getUseBoxes()) {
            if (vb.getValue() instanceof Local && ((Local) vb.getValue()).getType() instanceof NullType) {
                Local l = (Local) vb.getValue();
                Stmt s = (Stmt) u;
                boolean replace = false;
                if (s.containsArrayRef()) {
                    ArrayRef r = s.getArrayRef();
                    if (r.getBase() == l) {
                        replace = true;
                    }
                } else if (s.containsFieldRef()) {
                    FieldRef r = s.getFieldRef();
                    if (r instanceof InstanceFieldRef) {
                        InstanceFieldRef ir = (InstanceFieldRef) r;
                        if (ir.getBase() == l) {
                            replace = true;
                        }
                    }
                } else if (s.containsInvokeExpr()) {
                    InvokeExpr ie = s.getInvokeExpr();
                    if (ie instanceof InstanceInvokeExpr) {
                        InstanceInvokeExpr iie = (InstanceInvokeExpr) ie;
                        if (iie.getBase() == l) {
                            replace = true;
                        }
                    }
                }
                if (replace) {
                    unitToReplaceByException.add(u);
                }
            }
        }
    }
    for (Unit u : unitToReplaceByException) {
        soot.dexpler.Util.addExceptionAfterUnit(b, "java.lang.NullPointerException", u, "This statement would have triggered an Exception: " + u);
        b.getUnits().remove(u);
    }
    // should be done on a separate phase
    DeadAssignmentEliminator.v().transform(b);
    UnusedLocalEliminator.v().transform(b);
}
Also used : FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) ArrayList(java.util.ArrayList) Local(soot.Local) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Unit(soot.Unit) Stmt(soot.jimple.Stmt) ArrayRef(soot.jimple.ArrayRef) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) ValueBox(soot.ValueBox) InstanceFieldRef(soot.jimple.InstanceFieldRef) NullType(soot.NullType)

Example 4 with NullType

use of soot.NullType in project soot by Sable.

the class TypeResolverBV method assign_types_1_2.

private void assign_types_1_2() throws TypeException {
    for (Iterator<Local> localIt = stmtBody.getLocals().iterator(); localIt.hasNext(); ) {
        final Local local = localIt.next();
        TypeVariableBV var = typeVariable(local);
        if (var == null) {
            local.setType(RefType.v("java.lang.Object"));
        } else if (var.depth() == 0) {
            if (var.type() == null) {
                TypeVariableBV.error("Type Error(5):  Variable without type");
            } else {
                local.setType(var.type().type());
            }
        } else {
            TypeVariableBV element = var.element();
            for (int j = 1; j < var.depth(); j++) {
                element = element.element();
            }
            if (element.type() == null) {
                TypeVariableBV.error("Type Error(6):  Array variable without base type");
            } else if (element.type().type() instanceof NullType) {
                local.setType(NullType.v());
            } else {
                Type t = element.type().type();
                if (t instanceof IntType) {
                    local.setType(var.approx().type());
                } else {
                    local.setType(ArrayType.v(t, var.depth()));
                }
            }
        }
        if (DEBUG) {
            if ((var != null) && (var.approx() != null) && (var.approx().type() != null) && (local != null) && (local.getType() != null) && !local.getType().equals(var.approx().type())) {
                logger.debug("local: " + local + ", type: " + local.getType() + ", approx: " + var.approx().type());
            }
        }
    }
}
Also used : RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) ArrayType(soot.ArrayType) Type(soot.Type) Local(soot.Local) NullType(soot.NullType) IntType(soot.IntType)

Example 5 with NullType

use of soot.NullType 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)

Aggregations

NullType (soot.NullType)18 Type (soot.Type)15 Local (soot.Local)13 RefType (soot.RefType)12 IntType (soot.IntType)11 ArrayType (soot.ArrayType)10 Value (soot.Value)10 LongType (soot.LongType)9 DoubleType (soot.DoubleType)8 FloatType (soot.FloatType)8 CastExpr (soot.jimple.CastExpr)7 BooleanType (soot.BooleanType)6 PrimType (soot.PrimType)6 ValueBox (soot.ValueBox)6 ArrayRef (soot.jimple.ArrayRef)6 NullConstant (soot.jimple.NullConstant)6 ByteType (soot.ByteType)5 CharType (soot.CharType)5 ShortType (soot.ShortType)5 Unit (soot.Unit)5