示例#1
0
        public virtual VarVersionNode CreateNode(VarVersionPair ver)
        {
            VarVersionNode node;

            nodes.AddWithKey(node = new VarVersionNode(ver.var, ver.version), ver);
            return(node);
        }
示例#2
0
        private VBStyleCollection <BasicBlock, int> CreateBasicBlocks(short[] startblock,
                                                                      InstructionSequence instrseq, Dictionary <int, BasicBlock> mapInstrBlocks)
        {
            VBStyleCollection <BasicBlock, int> col = new VBStyleCollection <BasicBlock, int>();
            InstructionSequence currseq             = null;
            List <int>          lstOffs             = null;
            int        len          = startblock.Length;
            short      counter      = 0;
            int        blockoffset  = 0;
            BasicBlock currentBlock = null;

            for (int i = 0; i < len; i++)
            {
                if (startblock[i] == 1)
                {
                    currentBlock = new BasicBlock(++counter);
                    currseq      = currentBlock.GetSeq();
                    lstOffs      = currentBlock.GetInstrOldOffsets();
                    col.AddWithKey(currentBlock, currentBlock.id);
                    blockoffset = instrseq.GetOffset(i);
                }
                startblock[i] = counter;
                Sharpen.Collections.Put(mapInstrBlocks, i, currentBlock);
                currseq.AddInstruction(instrseq.GetInstr(i), instrseq.GetOffset(i) - blockoffset);
                lstOffs.Add(instrseq.GetOffset(i));
            }
            last_id = counter;
            return(col);
        }
 private void OrderNodes()
 {
     setRoots = graph.GetRoots();
     foreach (var node in graph.GetReversePostOrderList())
     {
         colOrderedIDoms.AddWithKey(null, node);
     }
 }
示例#4
0
        /// <exception cref="System.IO.IOException"/>
        private InstructionSequence ParseBytecode(DataInputFullStream @in, int length, ConstantPool
                                                  pool)
        {
            VBStyleCollection <Instruction, int> instructions = new VBStyleCollection <Instruction
                                                                                       , int>();
            int bytecode_version = classStruct.GetBytecodeVersion();

            for (int i = 0; i < length;)
            {
                int  offset = i;
                int  opcode = @in.ReadUnsignedByte();
                int  group  = Group_General;
                bool wide   = (opcode == opc_wide);
                if (wide)
                {
                    i++;
                    opcode = @in.ReadUnsignedByte();
                }
                List <int> operands = new List <int>();
                if (opcode >= opc_iconst_m1 && opcode <= opc_iconst_5)
                {
                    operands.Add(opr_iconst[opcode - opc_iconst_m1]);
                    opcode = opc_bipush;
                }
                else if (opcode >= opc_iload_0 && opcode <= opc_aload_3)
                {
                    operands.Add(opr_loadstore[opcode - opc_iload_0]);
                    opcode = opcs_load[(opcode - opc_iload_0) / 4];
                }
                else if (opcode >= opc_istore_0 && opcode <= opc_astore_3)
                {
                    operands.Add(opr_loadstore[opcode - opc_istore_0]);
                    opcode = opcs_store[(opcode - opc_istore_0) / 4];
                }
                else
                {
                    switch (opcode)
                    {
                    case opc_bipush:
                    {
                        operands.Add((int)@in.ReadByte());
                        i++;
                        break;
                    }

                    case opc_ldc:
                    case opc_newarray:
                    {
                        operands.Add(@in.ReadUnsignedByte());
                        i++;
                        break;
                    }

                    case opc_sipush:
                    case opc_ifeq:
                    case opc_ifne:
                    case opc_iflt:
                    case opc_ifge:
                    case opc_ifgt:
                    case opc_ifle:
                    case opc_if_icmpeq:
                    case opc_if_icmpne:
                    case opc_if_icmplt:
                    case opc_if_icmpge:
                    case opc_if_icmpgt:
                    case opc_if_icmple:
                    case opc_if_acmpeq:
                    case opc_if_acmpne:
                    case opc_goto:
                    case opc_jsr:
                    case opc_ifnull:
                    case opc_ifnonnull:
                    {
                        if (opcode != opc_sipush)
                        {
                            group = Group_Jump;
                        }
                        operands.Add((int)@in.ReadShort());
                        i += 2;
                        break;
                    }

                    case opc_ldc_w:
                    case opc_ldc2_w:
                    case opc_getstatic:
                    case opc_putstatic:
                    case opc_getfield:
                    case opc_putfield:
                    case opc_invokevirtual:
                    case opc_invokespecial:
                    case opc_invokestatic:
                    case opc_new:
                    case opc_anewarray:
                    case opc_checkcast:
                    case opc_instanceof:
                    {
                        operands.Add(@in.ReadUnsignedShort());
                        i += 2;
                        if (opcode >= opc_getstatic && opcode <= opc_putfield)
                        {
                            group = Group_Fieldaccess;
                        }
                        else if (opcode >= opc_invokevirtual && opcode <= opc_invokestatic)
                        {
                            group = Group_Invocation;
                        }
                        break;
                    }

                    case opc_invokedynamic:
                    {
                        if (classStruct.IsVersionGE_1_7())
                        {
                            // instruction unused in Java 6 and before
                            operands.Add(@in.ReadUnsignedShort());
                            @in.Discard(2);
                            group = Group_Invocation;
                            i    += 4;
                        }
                        break;
                    }

                    case opc_iload:
                    case opc_lload:
                    case opc_fload:
                    case opc_dload:
                    case opc_aload:
                    case opc_istore:
                    case opc_lstore:
                    case opc_fstore:
                    case opc_dstore:
                    case opc_astore:
                    case opc_ret:
                    {
                        if (wide)
                        {
                            operands.Add(@in.ReadUnsignedShort());
                            i += 2;
                        }
                        else
                        {
                            operands.Add(@in.ReadUnsignedByte());
                            i++;
                        }
                        if (opcode == opc_ret)
                        {
                            group = Group_Return;
                        }
                        break;
                    }

                    case opc_iinc:
                    {
                        if (wide)
                        {
                            operands.Add(@in.ReadUnsignedShort());
                            operands.Add((int)@in.ReadShort());
                            i += 4;
                        }
                        else
                        {
                            operands.Add(@in.ReadUnsignedByte());
                            operands.Add((int)@in.ReadByte());
                            i += 2;
                        }
                        break;
                    }

                    case opc_goto_w:
                    case opc_jsr_w:
                    {
                        opcode = opcode == opc_jsr_w ? opc_jsr : opc_goto;
                        operands.Add(@in.ReadInt());
                        group = Group_Jump;
                        i    += 4;
                        break;
                    }

                    case opc_invokeinterface:
                    {
                        operands.Add(@in.ReadUnsignedShort());
                        operands.Add(@in.ReadUnsignedByte());
                        @in.Discard(1);
                        group = Group_Invocation;
                        i    += 4;
                        break;
                    }

                    case opc_multianewarray:
                    {
                        operands.Add(@in.ReadUnsignedShort());
                        operands.Add(@in.ReadUnsignedByte());
                        i += 3;
                        break;
                    }

                    case opc_tableswitch:
                    {
                        @in.Discard((4 - (i + 1) % 4) % 4);
                        i += ((4 - (i + 1) % 4) % 4);
                        // padding
                        operands.Add(@in.ReadInt());
                        i += 4;
                        int low = @in.ReadInt();
                        operands.Add(low);
                        i += 4;
                        int high = @in.ReadInt();
                        operands.Add(high);
                        i += 4;
                        for (int j = 0; j < high - low + 1; j++)
                        {
                            operands.Add(@in.ReadInt());
                            i += 4;
                        }
                        group = Group_Switch;
                        break;
                    }

                    case opc_lookupswitch:
                    {
                        @in.Discard((4 - (i + 1) % 4) % 4);
                        i += ((4 - (i + 1) % 4) % 4);
                        // padding
                        operands.Add(@in.ReadInt());
                        i += 4;
                        int npairs = @in.ReadInt();
                        operands.Add(npairs);
                        i += 4;
                        for (int j = 0; j < npairs; j++)
                        {
                            operands.Add(@in.ReadInt());
                            i += 4;
                            operands.Add(@in.ReadInt());
                            i += 4;
                        }
                        group = Group_Switch;
                        break;
                    }

                    case opc_ireturn:
                    case opc_lreturn:
                    case opc_freturn:
                    case opc_dreturn:
                    case opc_areturn:
                    case opc_return:
                    case opc_athrow:
                    {
                        group = Group_Return;
                        break;
                    }
                    }
                }
                int[] ops = null;
                if (!(operands.Count == 0))
                {
                    ops = new int[operands.Count];
                    for (int j = 0; j < operands.Count; j++)
                    {
                        ops[j] = operands[j];
                    }
                }
                Instruction instr = Instruction.Create(opcode, wide, group, bytecode_version, ops
                                                       );
                instructions.AddWithKey(instr, offset);
                i++;
            }
            // initialize exception table
            List <ExceptionHandler> lstHandlers = new List <ExceptionHandler>();
            int exception_count = @in.ReadUnsignedShort();

            for (int i = 0; i < exception_count; i++)
            {
                ExceptionHandler handler = new ExceptionHandler();
                handler.from    = @in.ReadUnsignedShort();
                handler.to      = @in.ReadUnsignedShort();
                handler.handler = @in.ReadUnsignedShort();
                int excclass = @in.ReadUnsignedShort();
                if (excclass != 0)
                {
                    handler.exceptionClass = pool.GetPrimitiveConstant(excclass).GetString();
                }
                lstHandlers.Add(handler);
            }
            InstructionSequence seq = new FullInstructionSequence(instructions, new ExceptionTable
                                                                      (lstHandlers));
            // initialize instructions
            int i_1 = seq.Length() - 1;

            seq.SetPointer(i_1);
            while (i_1 >= 0)
            {
                Instruction instr = seq.GetInstr(i_1--);
                if (instr.group != Group_General)
                {
                    instr.InitInstruction(seq);
                }
                seq.AddToPointer(-1);
            }
            return(seq);
        }
示例#5
0
        public virtual void CollapseNodesToStatement(Statement stat)
        {
            Statement head = stat.GetFirst();
            Statement post = stat.GetPost();
            VBStyleCollection <Statement, int> setNodes = stat.GetStats();

            // post edges
            if (post != null)
            {
                foreach (StatEdge edge in post.GetEdges(Statedge_Direct_All, Direction_Backward))
                {
                    if (stat.ContainsStatementStrict(edge.GetSource()))
                    {
                        edge.GetSource().ChangeEdgeType(Direction_Forward, edge, StatEdge.Type_Break);
                        stat.AddLabeledEdge(edge);
                    }
                }
            }
            // regular head edges
            foreach (StatEdge prededge in head.GetAllPredecessorEdges())
            {
                if (prededge.GetType() != StatEdge.Type_Exception && stat.ContainsStatementStrict
                        (prededge.GetSource()))
                {
                    prededge.GetSource().ChangeEdgeType(Direction_Forward, prededge, StatEdge.Type_Continue
                                                        );
                    stat.AddLabeledEdge(prededge);
                }
                head.RemovePredecessor(prededge);
                prededge.GetSource().ChangeEdgeNode(Direction_Forward, prededge, stat);
                stat.AddPredecessor(prededge);
            }
            if (setNodes.ContainsKey(first.id))
            {
                first = stat;
            }
            // exception edges
            HashSet <Statement> setHandlers = new HashSet <Statement>(head.GetNeighbours(StatEdge
                                                                                         .Type_Exception, Direction_Forward));

            foreach (Statement node in setNodes)
            {
                setHandlers.UnionWith(node.GetNeighbours(StatEdge.Type_Exception, Direction_Forward
                                                         ));
            }
            if (!(setHandlers.Count == 0))
            {
                foreach (StatEdge edge in head.GetEdges(StatEdge.Type_Exception, Direction_Forward
                                                        ))
                {
                    Statement handler = edge.GetDestination();
                    if (setHandlers.Contains(handler))
                    {
                        if (!setNodes.ContainsKey(handler.id))
                        {
                            stat.AddSuccessor(new StatEdge(stat, handler, edge.GetExceptions()));
                        }
                    }
                }
                foreach (Statement node in setNodes)
                {
                    foreach (StatEdge edge in node.GetEdges(StatEdge.Type_Exception, Direction_Forward
                                                            ))
                    {
                        if (setHandlers.Contains(edge.GetDestination()))
                        {
                            node.RemoveSuccessor(edge);
                        }
                    }
                }
            }
            if (post != null && !stat.GetNeighbours(StatEdge.Type_Exception, Direction_Forward
                                                    ).Contains(post))
            {
                // TODO: second condition redundant?
                stat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, stat, post));
            }
            // adjust statement collection
            foreach (Statement st in setNodes)
            {
                stats.RemoveWithKey(st.id);
            }
            stats.AddWithKey(stat, stat.id);
            stat.SetAllParent();
            stat.SetParent(this);
            stat.BuildContinueSet();
            // monitorenter and monitorexit
            stat.BuildMonitorFlags();
            if (stat.type == Type_Switch)
            {
                // special case switch, sorting leaf nodes
                ((SwitchStatement)stat).SortEdgesAndNodes();
            }
        }
示例#6
0
        public virtual void Init()
        {
            DecompilerContext.SetProperty(DecompilerContext.Current_Class, classStruct);
            DecompilerContext.SetProperty(DecompilerContext.Current_Class_Wrapper, this);
            DecompilerContext.GetLogger().StartClass(classStruct.qualifiedName);
            int maxSec = System.Convert.ToInt32(DecompilerContext.GetProperty(IFernflowerPreferences
                                                                              .Max_Processing_Method).ToString());
            bool testMode = DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode
                                                        );

            foreach (StructMethod mt in classStruct.GetMethods())
            {
                DecompilerContext.GetLogger().StartMethod(mt.GetName() + " " + mt.GetDescriptor()
                                                          );
                MethodDescriptor md      = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                VarProcessor     varProc = new VarProcessor(mt, md);
                DecompilerContext.StartMethod(varProc);
                VarNamesCollector vc      = varProc.GetVarNamesCollector();
                CounterContainer  counter = DecompilerContext.GetCounterContainer();
                RootStatement     root    = null;
                bool isError = false;
                try
                {
                    if (mt.ContainsCode())
                    {
                        if (maxSec == 0 || testMode)
                        {
                            root = MethodProcessorRunnable.CodeToJava(mt, md, varProc);
                        }
                        else
                        {
                            MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext
                                                                                         .GetCurrentContext());
                            Thread mtThread = new Thread(o => mtProc.Run())
                            {
                                Name = "Java decompiler"
                            };
                            long stopAt = Runtime.CurrentTimeMillis() + maxSec * 1000L;
                            mtThread.Start();
                            while (!mtProc.IsFinished())
                            {
                                try
                                {
                                    lock (mtProc.Lock)
                                    {
                                        Thread.Sleep(200);
                                    }
                                }
                                catch (Exception e)
                                {
                                    KillThread(mtThread);
                                    throw;
                                }
                                if (Runtime.CurrentTimeMillis() >= stopAt)
                                {
                                    string message = "Processing time limit exceeded for method " + mt.GetName() + ", execution interrupted.";
                                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Error
                                                                               );
                                    KillThread(mtThread);
                                    isError = true;
                                    break;
                                }
                            }
                            if (!isError)
                            {
                                root = mtProc.GetResult();
                            }
                        }
                    }
                    else
                    {
                        bool thisVar    = !mt.HasModifier(ICodeConstants.Acc_Static);
                        int  paramCount = 0;
                        if (thisVar)
                        {
                            Sharpen.Collections.Put(varProc.GetThisVars(), new VarVersionPair(0, 0), classStruct
                                                    .qualifiedName);
                            paramCount = 1;
                        }
                        paramCount += [email protected];
                        int varIndex = 0;
                        for (int i = 0; i < paramCount; i++)
                        {
                            varProc.SetVarName(new VarVersionPair(varIndex, 0), vc.GetFreeName(varIndex));
                            if (thisVar)
                            {
                                if (i == 0)
                                {
                                    varIndex++;
                                }
                                else
                                {
                                    varIndex += md.@params[i - 1].stackSize;
                                }
                            }
                            else
                            {
                                varIndex += md.@params[i].stackSize;
                            }
                        }
                    }
                }
                catch (Exception t)
                {
                    string message = "Method " + mt.GetName() + " " + mt.GetDescriptor() + " couldn't be decompiled.";
                    DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn
                                                               , t);
                    isError = true;
                }
                MethodWrapper methodWrapper = new MethodWrapper(root, varProc, mt, counter);
                methodWrapper.decompiledWithErrors = isError;
                methods.AddWithKey(methodWrapper, InterpreterUtil.MakeUniqueKey(mt.GetName(), mt.
                                                                                GetDescriptor()));
                if (!isError)
                {
                    // rename vars so that no one has the same name as a field
                    VarNamesCollector namesCollector = new VarNamesCollector();
                    classStruct.GetFields().ForEach((StructField f) => namesCollector.AddName(f.GetName
                                                                                                  ()));
                    varProc.RefreshVarNames(namesCollector);
                    // if debug information present and should be used
                    if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names))
                    {
                        StructLocalVariableTableAttribute attr = mt.GetLocalVariableAttr();
                        if (attr != null)
                        {
                            // only param names here
                            varProc.SetDebugVarNames(attr.GetMapParamNames());
                            // the rest is here
                            methodWrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => {
                                List <Exprent> lst = exprent.GetAllExprents(true);
                                lst.Add(exprent);
                                lst.Where(e => e.type == Exprent.Exprent_Var).ToList().ForEach((Exprent
                                                                                                e) => {
                                    VarExprent varExprent = (VarExprent)e;
                                    string name           = varExprent.GetDebugName(mt);
                                    if (name != null)
                                    {
                                        varProc.SetVarName(varExprent.GetVarVersionPair(), name);
                                    }
                                }
                                                                                               );
                                return(0);
                            }
                                                                            );
                        }
                    }
                }
                DecompilerContext.GetLogger().EndMethod();
            }
            DecompilerContext.GetLogger().EndClass();
        }
示例#7
0
        public static VBStyleCollection <List <int>, int> CalcPostDominators(Statement container
                                                                             )
        {
            Dictionary <Statement, FastFixedSetFactory <Statement> .FastFixedSet <Statement> > lists = new Dictionary
                                                                                                       <Statement, FastFixedSetFactory <Statement> .FastFixedSet <Statement> >();
            StrongConnectivityHelper schelper   = new StrongConnectivityHelper(container);
            List <List <Statement> > components = schelper.GetComponents();
            List <Statement>         lstStats   = container.GetPostReversePostOrderList(StrongConnectivityHelper
                                                                                        .GetExitReps(components));
            FastFixedSetFactory <Statement> factory = new FastFixedSetFactory <Statement>(lstStats
                                                                                          );

            FastFixedSetFactory <Statement> .FastFixedSet <Statement> setFlagNodes = factory.SpawnEmptySet(
                );
            setFlagNodes.SetAllElements();
            FastFixedSetFactory <Statement> .FastFixedSet <Statement> initSet = factory.SpawnEmptySet();
            initSet.SetAllElements();
            foreach (List <Statement> lst in components)
            {
                FastFixedSetFactory <Statement> .FastFixedSet <Statement> tmpSet;
                if (StrongConnectivityHelper.IsExitComponent(lst))
                {
                    tmpSet = factory.SpawnEmptySet();
                    tmpSet.AddAll(lst);
                }
                else
                {
                    tmpSet = initSet.GetCopy();
                }
                foreach (Statement stat in lst)
                {
                    Sharpen.Collections.Put(lists, stat, tmpSet);
                }
            }
            do
            {
                foreach (Statement stat in lstStats)
                {
                    if (!setFlagNodes.Contains(stat))
                    {
                        continue;
                    }
                    setFlagNodes.Remove(stat);
                    FastFixedSetFactory <Statement> .FastFixedSet <Statement> doms      = lists.GetOrNull(stat);
                    FastFixedSetFactory <Statement> .FastFixedSet <Statement> domsSuccs = factory.SpawnEmptySet();
                    List <Statement> lstSuccs = stat.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Forward
                                                                   );
                    for (int j = 0; j < lstSuccs.Count; j++)
                    {
                        Statement succ = lstSuccs[j];
                        FastFixedSetFactory <Statement> .FastFixedSet <Statement> succlst = lists.GetOrNull(succ);
                        if (j == 0)
                        {
                            domsSuccs.Union(succlst);
                        }
                        else
                        {
                            domsSuccs.Intersection(succlst);
                        }
                    }
                    if (!domsSuccs.Contains(stat))
                    {
                        domsSuccs.Add(stat);
                    }
                    if (!InterpreterUtil.EqualObjects(domsSuccs, doms))
                    {
                        Sharpen.Collections.Put(lists, stat, domsSuccs);
                        List <Statement> lstPreds = stat.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Backward
                                                                       );
                        foreach (Statement pred in lstPreds)
                        {
                            setFlagNodes.Add(pred);
                        }
                    }
                }
            }while (!setFlagNodes.IsEmpty());
            VBStyleCollection <List <int>, int> ret = new VBStyleCollection <List <int>, int>();
            List <Statement> lstRevPost             = container.GetReversePostOrderList();
            // sort order crucial!
            Dictionary <int, int> mapSortOrder = new Dictionary <int, int>();

            for (int i = 0; i < lstRevPost.Count; i++)
            {
                Sharpen.Collections.Put(mapSortOrder, lstRevPost[i].id, i);
            }
            foreach (Statement st in lstStats)
            {
                List <int> lstPosts = new List <int>();
                foreach (Statement stt in lists.GetOrNull(st))
                {
                    lstPosts.Add(stt.id);
                }
                lstPosts = lstPosts.OrderBy(c => mapSortOrder[c]).ToList();
                if (lstPosts.Count > 1 && lstPosts[0] == st.id)
                {
                    lstPosts.Add(lstPosts.RemoveAtReturningValue(0));
                }
                ret.AddWithKey(lstPosts, st.id);
            }
            return(ret);
        }
示例#8
0
        private static Statement FindGeneralStatement(Statement stat, bool forceall, Dictionary
                                                      <int, HashSet <int> > mapExtPost)
        {
            VBStyleCollection <Statement, int>  stats = stat.GetStats();
            VBStyleCollection <List <int>, int> vbPost;

            if ((mapExtPost.Count == 0))
            {
                FastExtendedPostdominanceHelper extpost = new FastExtendedPostdominanceHelper();
                Sharpen.Collections.PutAll(mapExtPost, extpost.GetExtendedPostdominators(stat));
            }
            if (forceall)
            {
                vbPost = new VBStyleCollection <List <int>, int>();
                List <Statement> lstAll = stat.GetPostReversePostOrderList();
                foreach (Statement st in lstAll)
                {
                    HashSet <int> set = mapExtPost.GetOrNull(st.id);
                    if (set != null)
                    {
                        vbPost.AddWithKey(new List <int>(set), st.id);
                    }
                }
                // FIXME: sort order!!
                // tail statements
                HashSet <int> setFirst = mapExtPost.GetOrNull(stat.GetFirst().id);
                if (setFirst != null)
                {
                    foreach (int id in setFirst)
                    {
                        List <int> lst = vbPost.GetWithKey(id);
                        if (lst == null)
                        {
                            vbPost.AddWithKey(lst = new List <int>(), id);
                        }
                        lst.Add(id);
                    }
                }
            }
            else
            {
                vbPost = CalcPostDominators(stat);
            }
            for (int k = 0; k < vbPost.Count; k++)
            {
                int        headid = vbPost.GetKey(k);
                List <int> posts  = vbPost[k];
                if (!mapExtPost.ContainsKey(headid) && !(posts.Count == 1 && posts[0].Equals(headid
                                                                                             )))
                {
                    continue;
                }
                Statement     head        = stats.GetWithKey(headid);
                HashSet <int> setExtPosts = mapExtPost.GetOrNull(headid);
                foreach (int postId in posts)
                {
                    if (!postId.Equals(headid) && !setExtPosts.Contains(postId))
                    {
                        continue;
                    }
                    Statement post = stats.GetWithKey(postId);
                    if (post == null)
                    {
                        // possible in case of an inherited postdominance set
                        continue;
                    }
                    bool same = (post == head);
                    HashSet <Statement> setNodes = new HashSet <Statement>();
                    HashSet <Statement> setPreds = new HashSet <Statement>();
                    // collect statement nodes
                    HashSet <Statement> setHandlers = new HashSet <Statement>();
                    setHandlers.Add(head);
                    while (true)
                    {
                        bool hdfound = false;
                        foreach (Statement handler in setHandlers)
                        {
                            if (setNodes.Contains(handler))
                            {
                                continue;
                            }
                            bool addhd = (setNodes.Count == 0);
                            // first handler == head
                            if (!addhd)
                            {
                                List <Statement> hdsupp = handler.GetNeighbours(StatEdge.Type_Exception, Statement
                                                                                .Direction_Backward);
                                addhd = (setNodes.ContainsAll(hdsupp) && (setNodes.Count > hdsupp.Count || setNodes
                                                                          .Count == 1));
                            }
                            // strict subset
                            if (addhd)
                            {
                                LinkedList <Statement> lstStack = new LinkedList <Statement>();
                                lstStack.AddLast(handler);
                                while (!(lstStack.Count == 0))
                                {
                                    Statement st = lstStack.RemoveAtReturningValue(0);
                                    if (!(setNodes.Contains(st) || (!same && st == post)))
                                    {
                                        setNodes.Add(st);
                                        if (st != head)
                                        {
                                            // record predeccessors except for the head
                                            Sharpen.Collections.AddAll(setPreds, st.GetNeighbours(StatEdge.Type_Regular, Statement
                                                                                                  .Direction_Backward));
                                        }
                                        // put successors on the stack
                                        Sharpen.Collections.AddAll(lstStack, st.GetNeighbours(StatEdge.Type_Regular, Statement
                                                                                              .Direction_Forward));
                                        // exception edges
                                        Sharpen.Collections.AddAll(setHandlers, st.GetNeighbours(StatEdge.Type_Exception,
                                                                                                 Statement.Direction_Forward));
                                    }
                                }
                                hdfound = true;
                                setHandlers.Remove(handler);
                                break;
                            }
                        }
                        if (!hdfound)
                        {
                            break;
                        }
                    }
                    // check exception handlers
                    setHandlers.Clear();
                    foreach (Statement st in setNodes)
                    {
                        Sharpen.Collections.AddAll(setHandlers, st.GetNeighbours(StatEdge.Type_Exception,
                                                                                 Statement.Direction_Forward));
                    }
                    setHandlers.RemoveAll(setNodes);
                    bool excok = true;
                    foreach (Statement handler in setHandlers)
                    {
                        if (!handler.GetNeighbours(StatEdge.Type_Exception, Statement.Direction_Backward)
                            .ContainsAll(setNodes))
                        {
                            excok = false;
                            break;
                        }
                    }
                    // build statement and return
                    if (excok)
                    {
                        Statement res;
                        setPreds.RemoveAll(setNodes);
                        if (setPreds.Count == 0)
                        {
                            if ((setNodes.Count > 1 || head.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Backward
                                                                          ).Contains(head)) && setNodes.Count < stats.Count)
                            {
                                if (CheckSynchronizedCompleteness(setNodes))
                                {
                                    res = new GeneralStatement(head, setNodes, same ? null : post);
                                    stat.CollapseNodesToStatement(res);
                                    return(res);
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
示例#9
0
        private static RootStatement GraphToStatement(ControlFlowGraph graph)
        {
            VBStyleCollection <Statement, int>  stats  = new VBStyleCollection <Statement, int>();
            VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks();

            foreach (BasicBlock block in blocks)
            {
                stats.AddWithKey(new BasicBlockStatement(block), block.id);
            }
            BasicBlock firstblock = graph.GetFirst();
            // head statement
            Statement firstst = stats.GetWithKey(firstblock.id);
            // dummy exit statement
            DummyExitStatement dummyexit = new DummyExitStatement();
            Statement          general;

            if (stats.Count > 1 || firstblock.IsSuccessor(firstblock))
            {
                // multiple basic blocks or an infinite loop of one block
                general = new GeneralStatement(firstst, stats, null);
            }
            else
            {
                // one straightforward basic block
                RootStatement root = new RootStatement(firstst, dummyexit);
                firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root));
                return(root);
            }
            foreach (BasicBlock block in blocks)
            {
                Statement stat = stats.GetWithKey(block.id);
                foreach (BasicBlock succ in block.GetSuccs())
                {
                    Statement stsucc = stats.GetWithKey(succ.id);
                    int       type;
                    if (stsucc == firstst)
                    {
                        type = StatEdge.Type_Continue;
                    }
                    else if (graph.GetFinallyExits().Contains(block))
                    {
                        type   = StatEdge.Type_Finallyexit;
                        stsucc = dummyexit;
                    }
                    else if (succ.id == graph.GetLast().id)
                    {
                        type   = StatEdge.Type_Break;
                        stsucc = dummyexit;
                    }
                    else
                    {
                        type = StatEdge.Type_Regular;
                    }
                    stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general
                                                 : stsucc, (type == StatEdge.Type_Regular) ? null : general));
                }
                // exceptions edges
                foreach (BasicBlock succex in block.GetSuccExceptions())
                {
                    Statement         stsuccex = stats.GetWithKey(succex.id);
                    ExceptionRangeCFG range    = graph.GetExceptionRange(succex, block);
                    if (!range.IsCircular())
                    {
                        stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes()));
                    }
                }
            }
            general.BuildContinueSet();
            general.BuildMonitorFlags();
            return(new RootStatement(general, dummyexit));
        }
示例#10
0
        /// <exception cref="System.IO.IOException"/>
        public StructClass(DataInputFullStream @in, bool own, LazyLoader loader)
        {
            /*
             * class_file {
             * u4 magic;
             * u2 minor_version;
             * u2 major_version;
             * u2 constant_pool_count;
             * cp_info constant_pool[constant_pool_count-1];
             * u2 access_flags;
             * u2 this_class;
             * u2 super_class;
             * u2 interfaces_count;
             * u2 interfaces[interfaces_count];
             * u2 fields_count;
             * field_info fields[fields_count];
             * u2 methods_count;
             * method_info methods[methods_count];
             * u2 attributes_count;
             * attribute_info attributes[attributes_count];
             * }
             */
            this.own    = own;
            this.loader = loader;
            @in.Discard(4);
            minorVersion = @in.ReadUnsignedShort();
            majorVersion = @in.ReadUnsignedShort();
            pool         = new ConstantPool(@in);
            accessFlags  = @in.ReadUnsignedShort();
            int thisClassIdx  = @in.ReadUnsignedShort();
            int superClassIdx = @in.ReadUnsignedShort();

            qualifiedName = pool.GetPrimitiveConstant(thisClassIdx).GetString();
            superClass    = pool.GetPrimitiveConstant(superClassIdx);
            // interfaces
            int length = @in.ReadUnsignedShort();

            interfaces     = new int[length];
            interfaceNames = new string[length];
            for (int i = 0; i < length; i++)
            {
                interfaces[i]     = @in.ReadUnsignedShort();
                interfaceNames[i] = pool.GetPrimitiveConstant(interfaces[i]).GetString();
            }
            // fields
            length = @in.ReadUnsignedShort();
            fields = new VBStyleCollection <StructField, string>(length);
            for (int i = 0; i < length; i++)
            {
                StructField field = new StructField(@in, this);
                fields.AddWithKey(field, InterpreterUtil.MakeUniqueKey(field.GetName(), field.GetDescriptor
                                                                           ()));
            }
            // methods
            length  = @in.ReadUnsignedShort();
            methods = new VBStyleCollection <StructMethod, string>(length);
            for (int i = 0; i < length; i++)
            {
                StructMethod method = new StructMethod(@in, this);
                methods.AddWithKey(method, InterpreterUtil.MakeUniqueKey(method.GetName(), method
                                                                         .GetDescriptor()));
            }
            // attributes
            attributes = ReadAttributes(@in, pool);
            ReleaseResources();
        }
示例#11
0
 public virtual void AddInstruction(Instruction inst, int offset)
 {
     collinstr.AddWithKey(inst, offset);
 }
示例#12
0
        private void SplitJsrRange(BasicBlock jsr, BasicBlock ret, HashSet <BasicBlock> common_blocks
                                   )
        {
            List <BasicBlock>            lstNodes    = new List <BasicBlock>();
            Dictionary <int, BasicBlock> mapNewNodes = new Dictionary <int, BasicBlock>();

            lstNodes.Add(jsr);
            Sharpen.Collections.Put(mapNewNodes, jsr.id, jsr);
            while (!(lstNodes.Count == 0))
            {
                BasicBlock node = lstNodes.RemoveAtReturningValue(0);
                for (int j = 0; j < 2; j++)
                {
                    List <BasicBlock> lst;
                    if (j == 0)
                    {
                        if (node.GetLastInstruction().opcode == ICodeConstants.opc_ret)
                        {
                            if (node.GetSuccs().Contains(ret))
                            {
                                continue;
                            }
                        }
                        lst = node.GetSuccs();
                    }
                    else
                    {
                        if (node == jsr)
                        {
                            continue;
                        }
                        lst = node.GetSuccExceptions();
                    }
                    for (int i = lst.Count - 1; i >= 0; i--)
                    {
                        BasicBlock child   = lst[i];
                        int        childid = child.id;
                        if (mapNewNodes.ContainsKey(childid))
                        {
                            node.ReplaceSuccessor(child, mapNewNodes.GetOrNull(childid));
                        }
                        else if (common_blocks.Contains(child))
                        {
                            // make a copy of the current block
                            BasicBlock copy = child.Clone();
                            copy.id = ++last_id;
                            // copy all successors
                            if (copy.GetLastInstruction().opcode == ICodeConstants.opc_ret && child.GetSuccs(
                                    ).Contains(ret))
                            {
                                copy.AddSuccessor(ret);
                                child.RemoveSuccessor(ret);
                            }
                            else
                            {
                                for (int k = 0; k < child.GetSuccs().Count; k++)
                                {
                                    copy.AddSuccessor(child.GetSuccs()[k]);
                                }
                            }
                            for (int k = 0; k < child.GetSuccExceptions().Count; k++)
                            {
                                copy.AddSuccessorException(child.GetSuccExceptions()[k]);
                            }
                            lstNodes.Add(copy);
                            Sharpen.Collections.Put(mapNewNodes, childid, copy);
                            if (last.GetPreds().Contains(child))
                            {
                                last.AddPredecessor(copy);
                            }
                            node.ReplaceSuccessor(child, copy);
                            blocks.AddWithKey(copy, copy.id);
                        }
                        else
                        {
                            // stop at the first fixed node
                            //lstNodes.add(child);
                            Sharpen.Collections.Put(mapNewNodes, childid, child);
                        }
                    }
                }
            }
            // note: subroutines won't be copied!
            SplitJsrExceptionRanges(common_blocks, mapNewNodes);
        }