Search in sources :

Example 1 with SootFieldRef

use of soot.SootFieldRef in project soot by Sable.

the class AsmMethodSource method convertGetFieldInsn.

private void convertGetFieldInsn(FieldInsnNode insn) {
    StackFrame frame = getFrame(insn);
    Operand[] out = frame.out();
    Operand opr;
    Type type;
    if (out == null) {
        SootClass declClass = Scene.v().getSootClass(AsmUtil.toQualifiedName(insn.owner));
        type = AsmUtil.toJimpleType(insn.desc);
        Value val;
        SootFieldRef ref;
        if (insn.getOpcode() == GETSTATIC) {
            ref = Scene.v().makeFieldRef(declClass, insn.name, type, true);
            val = Jimple.v().newStaticFieldRef(ref);
        } else {
            Operand base = popLocal();
            ref = Scene.v().makeFieldRef(declClass, insn.name, type, false);
            InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(base.stackOrValue(), ref);
            val = ifr;
            base.addBox(ifr.getBaseBox());
            frame.in(base);
            frame.boxes(ifr.getBaseBox());
        }
        opr = new Operand(insn, val);
        frame.out(opr);
    } else {
        opr = out[0];
        type = opr.<FieldRef>value().getFieldRef().type();
        if (insn.getOpcode() == GETFIELD)
            frame.mergeIn(pop());
    }
    push(type, opr);
}
Also used : BooleanType(soot.BooleanType) Type(soot.Type) UnknownType(soot.UnknownType) ArrayType(soot.ArrayType) RefType(soot.RefType) ShortType(soot.ShortType) ByteType(soot.ByteType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) VoidType(soot.VoidType) Value(soot.Value) InstanceFieldRef(soot.jimple.InstanceFieldRef) SootClass(soot.SootClass) SootFieldRef(soot.SootFieldRef)

Example 2 with SootFieldRef

use of soot.SootFieldRef in project soot by Sable.

the class MethodNodeFactory method handleStmt.

/**
 * Adds the edges required for this statement to the graph.
 */
public final void handleStmt(Stmt s) {
    // We only consider reflective class creation when it is enabled
    if (s.containsInvokeExpr()) {
        if (!pag.getCGOpts().types_for_invoke())
            return;
        InvokeExpr iexpr = s.getInvokeExpr();
        if (iexpr instanceof VirtualInvokeExpr) {
            if (!isReflectionNewInstance(iexpr))
                return;
        } else if (!(iexpr instanceof StaticInvokeExpr))
            return;
    }
    s.apply(new AbstractStmtSwitch() {

        @Override
        public final void caseAssignStmt(AssignStmt as) {
            Value l = as.getLeftOp();
            Value r = as.getRightOp();
            if (!(l.getType() instanceof RefLikeType))
                return;
            assert r.getType() instanceof RefLikeType : "Type mismatch in assignment " + as + " in method " + method.getSignature();
            l.apply(MethodNodeFactory.this);
            Node dest = getNode();
            r.apply(MethodNodeFactory.this);
            Node src = getNode();
            if (l instanceof InstanceFieldRef) {
                ((InstanceFieldRef) l).getBase().apply(MethodNodeFactory.this);
                pag.addDereference((VarNode) getNode());
            }
            if (r instanceof InstanceFieldRef) {
                ((InstanceFieldRef) r).getBase().apply(MethodNodeFactory.this);
                pag.addDereference((VarNode) getNode());
            } else if (r instanceof StaticFieldRef) {
                StaticFieldRef sfr = (StaticFieldRef) r;
                SootFieldRef s = sfr.getFieldRef();
                if (pag.getOpts().empties_as_allocs()) {
                    if (s.declaringClass().getName().equals("java.util.Collections")) {
                        if (s.name().equals("EMPTY_SET")) {
                            src = pag.makeAllocNode(RefType.v("java.util.HashSet"), RefType.v("java.util.HashSet"), method);
                        } else if (s.name().equals("EMPTY_MAP")) {
                            src = pag.makeAllocNode(RefType.v("java.util.HashMap"), RefType.v("java.util.HashMap"), method);
                        } else if (s.name().equals("EMPTY_LIST")) {
                            src = pag.makeAllocNode(RefType.v("java.util.LinkedList"), RefType.v("java.util.LinkedList"), method);
                        }
                    } else if (s.declaringClass().getName().equals("java.util.Hashtable")) {
                        if (s.name().equals("emptyIterator")) {
                            src = pag.makeAllocNode(RefType.v("java.util.Hashtable$EmptyIterator"), RefType.v("java.util.Hashtable$EmptyIterator"), method);
                        } else if (s.name().equals("emptyEnumerator")) {
                            src = pag.makeAllocNode(RefType.v("java.util.Hashtable$EmptyEnumerator"), RefType.v("java.util.Hashtable$EmptyEnumerator"), method);
                        }
                    }
                }
            }
            mpag.addInternalEdge(src, dest);
        }

        @Override
        public final void caseReturnStmt(ReturnStmt rs) {
            if (!(rs.getOp().getType() instanceof RefLikeType))
                return;
            rs.getOp().apply(MethodNodeFactory.this);
            Node retNode = getNode();
            mpag.addInternalEdge(retNode, caseRet());
        }

        @Override
        public final void caseIdentityStmt(IdentityStmt is) {
            if (!(is.getLeftOp().getType() instanceof RefLikeType))
                return;
            Value leftOp = is.getLeftOp();
            Value rightOp = is.getRightOp();
            leftOp.apply(MethodNodeFactory.this);
            Node dest = getNode();
            rightOp.apply(MethodNodeFactory.this);
            Node src = getNode();
            mpag.addInternalEdge(src, dest);
            // in case library mode is activated add allocations to any
            // possible type of this local and
            // parameters of accessible methods
            int libOption = pag.getCGOpts().library();
            if (libOption != CGOptions.library_disabled && (accessibilityOracle.isAccessible(method))) {
                if (rightOp instanceof IdentityRef) {
                    Type rt = rightOp.getType();
                    rt.apply(new SparkLibraryHelper(pag, src, method));
                }
            }
        }

        @Override
        public final void caseThrowStmt(ThrowStmt ts) {
            ts.getOp().apply(MethodNodeFactory.this);
            mpag.addOutEdge(getNode(), pag.nodeFactory().caseThrow());
        }
    });
}
Also used : VarNode(soot.jimple.spark.pag.VarNode) AssignStmt(soot.jimple.AssignStmt) NewInstanceNode(soot.jimple.spark.pag.NewInstanceNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) SootFieldRef(soot.SootFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) RefLikeType(soot.RefLikeType) RefType(soot.RefType) Type(soot.Type) RefLikeType(soot.RefLikeType) ArrayType(soot.ArrayType) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) IdentityRef(soot.jimple.IdentityRef) AbstractStmtSwitch(soot.jimple.AbstractStmtSwitch) Value(soot.Value) InstanceFieldRef(soot.jimple.InstanceFieldRef) VirtualInvokeExpr(soot.jimple.VirtualInvokeExpr) ReturnStmt(soot.jimple.ReturnStmt) ThrowStmt(soot.jimple.ThrowStmt) IdentityStmt(soot.jimple.IdentityStmt) SparkLibraryHelper(soot.jimple.spark.internal.SparkLibraryHelper)

Example 3 with SootFieldRef

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

use of soot.SootFieldRef in project robovm by robovm.

the class MethodCompiler method canAccessDirectly.

//    private Value callOrInvoke(Unit unit, Value fn, Value ... args) {
//        Variable result = null;
//        Type returnType = ((FunctionType) fn.getType()).getReturnType();
//        if (returnType != VOID) {
//            result = this.function.newVariable(returnType);
//        }
//        List<Trap> traps = getTrapsAt(unit);
//        if (!traps.isEmpty()) {
//            Label label = new Label();
//            BasicBlockRef to = function.newBasicBlockRef(label);
//            BasicBlockRef unwind = function.newBasicBlockRef(new Label(traps));
//            function.add(new Invoke(result, fn, to, unwind, args));
//            function.newBasicBlock(label);
//            recordedTraps.add(traps);
//        } else {
//            function.add(new Call(result, fn, args));
//        }
//        return result == null ? null : result.ref();
//    }
private boolean canAccessDirectly(FieldRef ref) {
    SootClass sootClass = this.sootMethod.getDeclaringClass();
    SootFieldRef fieldRef = ref.getFieldRef();
    if (!fieldRef.declaringClass().equals(sootClass)) {
        return false;
    }
    try {
        SootField field = sootClass.getField(fieldRef.name(), fieldRef.type());
        /* 
             * The field exists.
             */
        if (field.isStatic()) {
            // If not we want an exception to be thrown so we need a trampoline.
            return ref instanceof StaticFieldRef;
        }
        // If not we want an exception to be thrown so we need a trampoline.
        return ref instanceof InstanceFieldRef;
    } catch (RuntimeException e) {
        // isn't declared in the class.
        return false;
    }
}
Also used : InstanceFieldRef(soot.jimple.InstanceFieldRef) SootField(soot.SootField) SootClass(soot.SootClass) SootFieldRef(soot.SootFieldRef) StaticFieldRef(soot.jimple.StaticFieldRef)

Example 5 with SootFieldRef

use of soot.SootFieldRef in project soot by Sable.

the class ReflectiveCallsInliner method initializeReflectiveCallsTable.

private void initializeReflectiveCallsTable() {
    int callSiteId = 0;
    SootClass reflCallsClass = Scene.v().getSootClass("soot.rtlib.tamiflex.ReflectiveCalls");
    SootMethod clinit = reflCallsClass.getMethodByName(SootMethod.staticInitializerName);
    Body body = clinit.retrieveActiveBody();
    PatchingChain<Unit> units = body.getUnits();
    LocalGenerator localGen = new LocalGenerator(body);
    Chain<Unit> newUnits = new HashChain<Unit>();
    SootClass setClass = Scene.v().getSootClass("java.util.Set");
    SootMethodRef addMethodRef = setClass.getMethodByName("add").makeRef();
    for (SootMethod m : RTI.methodsContainingReflectiveCalls()) {
        {
            if (!RTI.classForNameClassNames(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "classForName", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String className : RTI.classForNameClassNames(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + className));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
        {
            if (!RTI.classNewInstanceClassNames(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "classNewInstance", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String className : RTI.classNewInstanceClassNames(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + className));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
        {
            if (!RTI.constructorNewInstanceSignatures(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "constructorNewInstance", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String constrSig : RTI.constructorNewInstanceSignatures(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + constrSig));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
        {
            if (!RTI.methodInvokeSignatures(m).isEmpty()) {
                SootFieldRef fieldRef = Scene.v().makeFieldRef(reflCallsClass, "methodInvoke", RefType.v("java.util.Set"), true);
                Local setLocal = localGen.generateLocal(RefType.v("java.util.Set"));
                newUnits.add(Jimple.v().newAssignStmt(setLocal, Jimple.v().newStaticFieldRef(fieldRef)));
                for (String methodSig : RTI.methodInvokeSignatures(m)) {
                    InterfaceInvokeExpr invokeExpr = Jimple.v().newInterfaceInvokeExpr(setLocal, addMethodRef, StringConstant.v(callSiteId + methodSig));
                    newUnits.add(Jimple.v().newInvokeStmt(invokeExpr));
                }
                callSiteId++;
            }
        }
    }
    Unit secondLastStmt = units.getPredOf(units.getLast());
    units.insertAfter(newUnits, secondLastStmt);
    if (Options.v().validate())
        body.validate();
}
Also used : LocalGenerator(soot.javaToJimple.LocalGenerator) HashChain(soot.util.HashChain) SootMethodRef(soot.SootMethodRef) Local(soot.Local) InterfaceInvokeExpr(soot.jimple.InterfaceInvokeExpr) SootClass(soot.SootClass) Unit(soot.Unit) SootFieldRef(soot.SootFieldRef) SootMethod(soot.SootMethod) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody)

Aggregations

SootFieldRef (soot.SootFieldRef)14 RefType (soot.RefType)9 SootClass (soot.SootClass)9 Type (soot.Type)9 ArrayType (soot.ArrayType)8 BooleanType (soot.BooleanType)7 DoubleType (soot.DoubleType)7 FloatType (soot.FloatType)7 IntType (soot.IntType)7 LongType (soot.LongType)7 Value (soot.Value)7 ByteType (soot.ByteType)6 CharType (soot.CharType)6 ShortType (soot.ShortType)6 VoidType (soot.VoidType)6 InstanceFieldRef (soot.jimple.InstanceFieldRef)6 Local (soot.Local)5 SootMethodRef (soot.SootMethodRef)5 List (java.util.List)4 UnknownType (soot.UnknownType)4