Search in sources :

Example 1 with ArrayType

use of soot.ArrayType in project robovm by robovm.

the class MarshalerLookup method getBaseType.

private soot.Type getBaseType(SootMethod m, AnnotationTag anno) {
    AnnotationClassElem el = (AnnotationClassElem) getElemByName(anno, "baseType");
    if (el != null) {
        switch(el.getDesc().charAt(0)) {
            case 'Z':
                return BooleanType.v();
            case 'B':
                return ByteType.v();
            case 'S':
                return ShortType.v();
            case 'C':
                return CharType.v();
            case 'I':
                return IntType.v();
            case 'J':
                return LongType.v();
            case 'F':
                return FloatType.v();
            case 'D':
                return DoubleType.v();
        }
        return null;
    }
    soot.Type t = m.getReturnType();
    if (t == VoidType.v()) {
        t = m.getParameterType(0);
    }
    if (t instanceof RefType) {
        SootClass c = ((RefType) t).getSootClass();
        if (isInstanceOfClass(c, "java.nio.ByteBuffer")) {
            return ByteType.v();
        } else if (isInstanceOfClass(c, "java.nio.ShortBuffer")) {
            return ShortType.v();
        } else if (isInstanceOfClass(c, "java.nio.CharBuffer")) {
            return CharType.v();
        } else if (isInstanceOfClass(c, "java.nio.IntBuffer")) {
            return IntType.v();
        } else if (isInstanceOfClass(c, "java.nio.LongBuffer")) {
            return LongType.v();
        } else if (isInstanceOfClass(c, "java.nio.FloatBuffer")) {
            return FloatType.v();
        } else if (isInstanceOfClass(c, "java.nio.DoubleBuffer")) {
            return DoubleType.v();
        } else if (isInstanceOfClass(c, "org.robovm.rt.bro.Struct")) {
            return config.getClazzes().load("org/robovm/rt/bro/Struct").getSootClass().getType();
        }
    } else if (t instanceof ArrayType) {
        ArrayType arrayType = (ArrayType) t;
        if (arrayType.baseType instanceof PrimType || isInstanceOfClass(arrayType.baseType, "org.robovm.rt.bro.Struct")) {
            return arrayType.baseType;
        }
    }
    return null;
}
Also used : RefType(soot.RefType) ArrayType(soot.ArrayType) AnnotationClassElem(soot.tagkit.AnnotationClassElem) PrimType(soot.PrimType) SootClass(soot.SootClass)

Example 2 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class AsmMethodSource method convertMultiANewArrayInsn.

private void convertMultiANewArrayInsn(MultiANewArrayInsnNode insn) {
    StackFrame frame = getFrame(insn);
    Operand[] out = frame.out();
    Operand opr;
    if (out == null) {
        ArrayType t = (ArrayType) AsmUtil.toJimpleType(insn.desc);
        int dims = insn.dims;
        Operand[] sizes = new Operand[dims];
        Value[] sizeVals = new Value[dims];
        ValueBox[] boxes = new ValueBox[dims];
        while (dims-- != 0) {
            sizes[dims] = popImmediate();
            sizeVals[dims] = sizes[dims].stackOrValue();
        }
        NewMultiArrayExpr nm = Jimple.v().newNewMultiArrayExpr(t, Arrays.asList(sizeVals));
        for (int i = 0; i != boxes.length; i++) {
            ValueBox vb = nm.getSizeBox(i);
            sizes[i].addBox(vb);
            boxes[i] = vb;
        }
        frame.boxes(boxes);
        frame.in(sizes);
        opr = new Operand(insn, nm);
        frame.out(opr);
    } else {
        opr = out[0];
        int dims = insn.dims;
        Operand[] sizes = new Operand[dims];
        while (dims-- != 0) sizes[dims] = pop();
        frame.mergeIn(sizes);
    }
    push(opr);
}
Also used : ArrayType(soot.ArrayType) ValueBox(soot.ValueBox) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) Value(soot.Value)

Example 3 with ArrayType

use of soot.ArrayType 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 4 with ArrayType

use of soot.ArrayType in project soot by Sable.

the class ConstraintCollector method caseAssignStmt.

public void caseAssignStmt(AssignStmt stmt) {
    Value l = stmt.getLeftOp();
    Value r = stmt.getRightOp();
    TypeVariable left = null;
    TypeVariable right = null;
    if (l instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) l;
        Value base = ref.getBase();
        Value index = ref.getIndex();
        TypeVariable baseType = resolver.typeVariable((Local) base);
        baseType.makeElement();
        left = baseType.element();
        if (index instanceof Local) {
            if (uses) {
                resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (l instanceof Local) {
        left = resolver.typeVariable((Local) l);
    } else if (l instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) l;
        if (uses) {
            TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
            baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
            left = resolver.typeVariable(ref.getField().getType());
        }
    } else if (l instanceof StaticFieldRef) {
        if (uses) {
            StaticFieldRef ref = (StaticFieldRef) l;
            left = resolver.typeVariable(ref.getField().getType());
        }
    } else {
        throw new RuntimeException("Unhandled assignment left hand side type: " + l.getClass());
    }
    if (r instanceof ArrayRef) {
        ArrayRef ref = (ArrayRef) r;
        Value base = ref.getBase();
        Value index = ref.getIndex();
        TypeVariable baseType = resolver.typeVariable((Local) base);
        baseType.makeElement();
        right = baseType.element();
        if (index instanceof Local) {
            if (uses) {
                resolver.typeVariable((Local) index).addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (r instanceof DoubleConstant) {
        right = resolver.typeVariable(DoubleType.v());
    } else if (r instanceof FloatConstant) {
        right = resolver.typeVariable(FloatType.v());
    } else if (r instanceof IntConstant) {
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof LongConstant) {
        right = resolver.typeVariable(LongType.v());
    } else if (r instanceof NullConstant) {
        right = resolver.typeVariable(NullType.v());
    } else if (r instanceof StringConstant) {
        right = resolver.typeVariable(RefType.v("java.lang.String"));
    } else if (r instanceof ClassConstant) {
        right = resolver.typeVariable(RefType.v("java.lang.Class"));
    } else if (r instanceof BinopExpr) {
        // ******** BINOP EXPR ********
        BinopExpr be = (BinopExpr) r;
        Value lv = be.getOp1();
        Value rv = be.getOp2();
        TypeVariable lop;
        TypeVariable rop;
        // ******** LEFT ********
        if (lv instanceof Local) {
            lop = resolver.typeVariable((Local) lv);
        } else if (lv instanceof DoubleConstant) {
            lop = resolver.typeVariable(DoubleType.v());
        } else if (lv instanceof FloatConstant) {
            lop = resolver.typeVariable(FloatType.v());
        } else if (lv instanceof IntConstant) {
            lop = resolver.typeVariable(IntType.v());
        } else if (lv instanceof LongConstant) {
            lop = resolver.typeVariable(LongType.v());
        } else if (lv instanceof NullConstant) {
            lop = resolver.typeVariable(NullType.v());
        } else if (lv instanceof StringConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (lv instanceof ClassConstant) {
            lop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression left operand type: " + lv.getClass());
        }
        // ******** RIGHT ********
        if (rv instanceof Local) {
            rop = resolver.typeVariable((Local) rv);
        } else if (rv instanceof DoubleConstant) {
            rop = resolver.typeVariable(DoubleType.v());
        } else if (rv instanceof FloatConstant) {
            rop = resolver.typeVariable(FloatType.v());
        } else if (rv instanceof IntConstant) {
            rop = resolver.typeVariable(IntType.v());
        } else if (rv instanceof LongConstant) {
            rop = resolver.typeVariable(LongType.v());
        } else if (rv instanceof NullConstant) {
            rop = resolver.typeVariable(NullType.v());
        } else if (rv instanceof StringConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.String"));
        } else if (rv instanceof ClassConstant) {
            rop = resolver.typeVariable(RefType.v("java.lang.Class"));
        } else {
            throw new RuntimeException("Unhandled binary expression right operand type: " + rv.getClass());
        }
        if ((be instanceof AddExpr) || (be instanceof SubExpr) || (be instanceof MulExpr) || (be instanceof DivExpr) || (be instanceof RemExpr) || (be instanceof AndExpr) || (be instanceof OrExpr) || (be instanceof XorExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                rop.addParent(common);
                lop.addParent(common);
            }
            if (left != null) {
                rop.addParent(left);
                lop.addParent(left);
            }
        } else if ((be instanceof ShlExpr) || (be instanceof ShrExpr) || (be instanceof UshrExpr)) {
            if (uses) {
                rop.addParent(resolver.typeVariable(IntType.v()));
            }
            right = lop;
        } else if ((be instanceof CmpExpr) || (be instanceof CmpgExpr) || (be instanceof CmplExpr) || (be instanceof EqExpr) || (be instanceof GeExpr) || (be instanceof GtExpr) || (be instanceof LeExpr) || (be instanceof LtExpr) || (be instanceof NeExpr)) {
            if (uses) {
                TypeVariable common = resolver.typeVariable();
                rop.addParent(common);
                lop.addParent(common);
            }
            right = resolver.typeVariable(IntType.v());
        } else {
            throw new RuntimeException("Unhandled binary expression type: " + be.getClass());
        }
    } else if (r instanceof CastExpr) {
        CastExpr ce = (CastExpr) r;
        right = resolver.typeVariable(ce.getCastType());
    } else if (r instanceof InstanceOfExpr) {
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof InvokeExpr) {
        InvokeExpr ie = (InvokeExpr) r;
        handleInvokeExpr(ie);
        right = resolver.typeVariable(ie.getMethodRef().returnType());
    } else if (r instanceof NewArrayExpr) {
        NewArrayExpr nae = (NewArrayExpr) r;
        Type baseType = nae.getBaseType();
        if (baseType instanceof ArrayType) {
            right = resolver.typeVariable(ArrayType.v(((ArrayType) baseType).baseType, ((ArrayType) baseType).numDimensions + 1));
        } else {
            right = resolver.typeVariable(ArrayType.v(baseType, 1));
        }
        if (uses) {
            Value size = nae.getSize();
            if (size instanceof Local) {
                TypeVariable var = resolver.typeVariable((Local) size);
                var.addParent(resolver.typeVariable(IntType.v()));
            }
        }
    } else if (r instanceof NewExpr) {
        NewExpr na = (NewExpr) r;
        right = resolver.typeVariable(na.getBaseType());
    } else if (r instanceof NewMultiArrayExpr) {
        NewMultiArrayExpr nmae = (NewMultiArrayExpr) r;
        right = resolver.typeVariable(nmae.getBaseType());
        if (uses) {
            for (int i = 0; i < nmae.getSizeCount(); i++) {
                Value size = nmae.getSize(i);
                if (size instanceof Local) {
                    TypeVariable var = resolver.typeVariable((Local) size);
                    var.addParent(resolver.typeVariable(IntType.v()));
                }
            }
        }
    } else if (r instanceof LengthExpr) {
        LengthExpr le = (LengthExpr) r;
        if (uses) {
            if (le.getOp() instanceof Local) {
                resolver.typeVariable((Local) le.getOp()).makeElement();
            }
        }
        right = resolver.typeVariable(IntType.v());
    } else if (r instanceof NegExpr) {
        NegExpr ne = (NegExpr) r;
        if (ne.getOp() instanceof Local) {
            right = resolver.typeVariable((Local) ne.getOp());
        } else if (ne.getOp() instanceof DoubleConstant) {
            right = resolver.typeVariable(DoubleType.v());
        } else if (ne.getOp() instanceof FloatConstant) {
            right = resolver.typeVariable(FloatType.v());
        } else if (ne.getOp() instanceof IntConstant) {
            right = resolver.typeVariable(IntType.v());
        } else if (ne.getOp() instanceof LongConstant) {
            right = resolver.typeVariable(LongType.v());
        } else {
            throw new RuntimeException("Unhandled neg expression operand type: " + ne.getOp().getClass());
        }
    } else if (r instanceof Local) {
        right = resolver.typeVariable((Local) r);
    } else if (r instanceof InstanceFieldRef) {
        InstanceFieldRef ref = (InstanceFieldRef) r;
        if (uses) {
            TypeVariable baseType = resolver.typeVariable((Local) ref.getBase());
            baseType.addParent(resolver.typeVariable(ref.getField().getDeclaringClass()));
        }
        right = resolver.typeVariable(ref.getField().getType());
    } else if (r instanceof StaticFieldRef) {
        StaticFieldRef ref = (StaticFieldRef) r;
        right = resolver.typeVariable(ref.getField().getType());
    } else {
        throw new RuntimeException("Unhandled assignment right hand side type: " + r.getClass());
    }
    if (left != null && right != null) {
        right.addParent(left);
    }
}
Also used : MulExpr(soot.jimple.MulExpr) AndExpr(soot.jimple.AndExpr) DoubleConstant(soot.jimple.DoubleConstant) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) FloatConstant(soot.jimple.FloatConstant) GtExpr(soot.jimple.GtExpr) LtExpr(soot.jimple.LtExpr) NegExpr(soot.jimple.NegExpr) GeExpr(soot.jimple.GeExpr) UshrExpr(soot.jimple.UshrExpr) LeExpr(soot.jimple.LeExpr) ArrayRef(soot.jimple.ArrayRef) ArrayType(soot.ArrayType) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) DynamicInvokeExpr(soot.jimple.DynamicInvokeExpr) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) CastExpr(soot.jimple.CastExpr) IntConstant(soot.jimple.IntConstant) ShlExpr(soot.jimple.ShlExpr) LongConstant(soot.jimple.LongConstant) XorExpr(soot.jimple.XorExpr) NeExpr(soot.jimple.NeExpr) LengthExpr(soot.jimple.LengthExpr) SubExpr(soot.jimple.SubExpr) Local(soot.Local) NullConstant(soot.jimple.NullConstant) AddExpr(soot.jimple.AddExpr) InstanceOfExpr(soot.jimple.InstanceOfExpr) OrExpr(soot.jimple.OrExpr) StaticFieldRef(soot.jimple.StaticFieldRef) DivExpr(soot.jimple.DivExpr) RefType(soot.RefType) Type(soot.Type) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) ArrayType(soot.ArrayType) NewArrayExpr(soot.jimple.NewArrayExpr) RemExpr(soot.jimple.RemExpr) ShrExpr(soot.jimple.ShrExpr) CmpExpr(soot.jimple.CmpExpr) EqExpr(soot.jimple.EqExpr) CmpgExpr(soot.jimple.CmpgExpr) Value(soot.Value) NewExpr(soot.jimple.NewExpr) StringConstant(soot.jimple.StringConstant) CmplExpr(soot.jimple.CmplExpr) ClassConstant(soot.jimple.ClassConstant) BinopExpr(soot.jimple.BinopExpr)

Example 5 with ArrayType

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

ArrayType (soot.ArrayType)44 Type (soot.Type)34 RefType (soot.RefType)26 Local (soot.Local)19 Value (soot.Value)18 IntType (soot.IntType)17 BooleanType (soot.BooleanType)14 NewArrayExpr (soot.jimple.NewArrayExpr)13 ByteType (soot.ByteType)12 FloatType (soot.FloatType)12 NullType (soot.NullType)12 ShortType (soot.ShortType)12 ArrayRef (soot.jimple.ArrayRef)12 CharType (soot.CharType)11 DoubleType (soot.DoubleType)11 LongType (soot.LongType)11 AssignStmt (soot.jimple.AssignStmt)11 SootClass (soot.SootClass)10 InvokeExpr (soot.jimple.InvokeExpr)10 PrimType (soot.PrimType)9