예제 #1
0
 private static void UpdateVersions(DirectGraph graph, Dictionary <VarVersionPair,
                                                                   int> versions)
 {
     graph.IterateExprents((Exprent exprent) => {
         List <Exprent> lst = exprent.GetAllExprents(true);
         lst.Add(exprent);
         foreach (Exprent expr in lst)
         {
             if (expr.type == Exprent.Exprent_Var)
             {
                 VarExprent var = (VarExprent)expr;
                 int?version    = versions.GetOrNullable(new VarVersionPair(var));
                 if (version != null)
                 {
                     var.SetVersion(version.Value);
                 }
             }
         }
         return(0);
     }
                           );
 }
예제 #2
0
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr, Statement
                                    stat, bool calcLiveVars)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg, stat, calcLiveVars);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr, stat, calcLiveVars);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (!finished)
            {
                List <Exprent> lst = expr.GetAllExprents();
                lst.Remove(varassign);
                foreach (Exprent ex in lst)
                {
                    ProcessExprent(ex, varmaparr, stat, calcLiveVars);
                }
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            // field access
            if (expr.type == Exprent.Exprent_Field)
            {
                int?index;
                if (mapFieldVars.ContainsKey(expr.id))
                {
                    index = mapFieldVars.GetOrNullable(expr.id);
                }
                else
                {
                    index = fieldvarcounter--;
                    Sharpen.Collections.Put(mapFieldVars, expr.id, index);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(index, 1));
                }
                SetCurrentVar(varmap, index, 1);
            }
            else if (expr.type == Exprent.Exprent_Invocation || (expr.type == Exprent.Exprent_Assignment &&
                                                                 ((AssignmentExprent)expr).GetLeft().type == Exprent.Exprent_Field) || (expr.
                                                                                                                                        type == Exprent.Exprent_New && ((NewExprent)expr).GetNewType().type == ICodeConstants
                                                                                                                                        .Type_Object) || expr.type == Exprent.Exprent_Function)
            {
                bool ismmpp = true;
                if (expr.type == Exprent.Exprent_Function)
                {
                    ismmpp = false;
                    FunctionExprent fexpr = (FunctionExprent)expr;
                    if (fexpr.GetFuncType() >= FunctionExprent.Function_Imm && fexpr.GetFuncType() <=
                        FunctionExprent.Function_Ppi)
                    {
                        if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Field)
                        {
                            ismmpp = true;
                        }
                    }
                }
                if (ismmpp)
                {
                    varmap.RemoveAllFields();
                }
            }
            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex, stat);
                    // set version
                    varassign.SetVersion(nextver);
                    // ssu graph
                    ssuversions.CreateNode(new VarVersionPair(varindex, nextver));
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    if (calcLiveVars)
                    {
                        VarMapToGraph(new VarVersionPair(varindex, varassign.GetVersion()), varmap);
                    }
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Function)
            {
                // MM or PP function
                FunctionExprent func_1 = (FunctionExprent)expr;
                switch (func_1.GetFuncType())
                {
                case FunctionExprent.Function_Imm:
                case FunctionExprent.Function_Mmi:
                case FunctionExprent.Function_Ipp:
                case FunctionExprent.Function_Ppi:
                {
                    if (func_1.GetLstOperands()[0].type == Exprent.Exprent_Var)
                    {
                        VarExprent     var      = (VarExprent)func_1.GetLstOperands()[0];
                        int            varindex = var.GetIndex();
                        VarVersionPair varpaar  = new VarVersionPair(varindex, var.GetVersion());
                        // ssu graph
                        VarVersionPair phantomver = phantomppnodes.GetOrNull(varpaar);
                        if (phantomver == null)
                        {
                            // get next version
                            int nextver = GetNextFreeVersion(varindex, null);
                            phantomver = new VarVersionPair(varindex, nextver);
                            //ssuversions.createOrGetNode(phantomver);
                            ssuversions.CreateNode(phantomver);
                            VarVersionNode vernode = ssuversions.nodes.GetWithKey(varpaar);
                            FastSparseSetFactory <int> .FastSparseSet <int> vers = factory.SpawnEmptySet();
                            if (vernode.preds.Count == 1)
                            {
                                vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(vernode.preds.GetEnumerator()).Next().source.version);
                            }
                            else
                            {
                                foreach (VarVersionEdge edge in vernode.preds)
                                {
                                    vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version);
                                }
                            }
                            vers.Add(nextver);
                            CreateOrUpdatePhiNode(varpaar, vers, stat);
                            Sharpen.Collections.Put(phantomppnodes, varpaar, phantomver);
                        }
                        if (calcLiveVars)
                        {
                            VarMapToGraph(varpaar, varmap);
                        }
                        SetCurrentVar(varmap, varindex, var.GetVersion());
                    }
                    break;
                }
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest      = (VarExprent)expr;
                int        varindex     = vardest.GetIndex();
                int        current_vers = vardest.GetVersion();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // size == 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split last version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        SetCurrentVar(varmap, varindex, usever);
                        // ssu graph
                        int            lastver = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                        VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(varindex
                                                                                                 , lastver));
                        VarVersionNode usenode = ssuversions.CreateNode(new VarVersionPair(varindex, usever
                                                                                           ));
                        VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, usenode
                                                                 );
                        prenode.AddSuccessor(edge);
                        usenode.AddPredecessor(edge);
                    }
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    if (current_vers != 0)
                    {
                        if (calcLiveVars)
                        {
                            VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap);
                        }
                        SetCurrentVar(varmap, varindex, current_vers);
                    }
                    else
                    {
                        // split version
                        int usever = GetNextFreeVersion(varindex, stat);
                        // set version
                        vardest.SetVersion(usever);
                        // ssu node
                        ssuversions.CreateNode(new VarVersionPair(varindex, usever));
                        SetCurrentVar(varmap, varindex, usever);
                        current_vers = usever;
                    }
                    CreateOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat);
                }
            }
        }
        private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr)
        {
            if (expr == null)
            {
                return;
            }
            VarExprent varassign = null;
            bool       finished  = false;

            switch (expr.type)
            {
            case Exprent.Exprent_Assignment:
            {
                AssignmentExprent assexpr = (AssignmentExprent)expr;
                if (assexpr.GetCondType() == AssignmentExprent.Condition_None)
                {
                    Exprent dest = assexpr.GetLeft();
                    if (dest.type == Exprent.Exprent_Var)
                    {
                        varassign = (VarExprent)dest;
                    }
                }
                break;
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)expr;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect varmapFalse;
                    if (varmaparr[1] == null)
                    {
                        varmapFalse = new SFormsFastMapDirect(varmaparr[0]);
                    }
                    else
                    {
                        varmapFalse  = varmaparr[1];
                        varmaparr[1] = null;
                    }
                    ProcessExprent(func.GetLstOperands()[1], varmaparr);
                    SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null };
                    ProcessExprent(func.GetLstOperands()[2], varmaparrNeg);
                    MergeMaps(varmaparr[0], varmaparrNeg[0]);
                    varmaparr[1] = null;
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cadd:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                         (varmaparr[0]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrAnd);
                    // false map
                    varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd
                                                                                                   [1] == null ? 0 : 1]);
                    // true map
                    varmaparr[0] = varmaparrAnd[0];
                    finished     = true;
                    break;
                }

                case FunctionExprent.Function_Cor:
                {
                    ProcessExprent(func.GetLstOperands()[0], varmaparr);
                    SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect
                                                                                        (varmaparr[varmaparr[1] == null ? 0 : 1]), null };
                    ProcessExprent(func.GetLstOperands()[1], varmaparrOr);
                    // false map
                    varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1];
                    // true map
                    varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]);
                    finished     = true;
                    break;
                }
                }
                break;
            }
            }
            if (finished)
            {
                return;
            }
            List <Exprent> lst = expr.GetAllExprents();

            lst.Remove(varassign);
            foreach (Exprent ex in lst)
            {
                ProcessExprent(ex, varmaparr);
            }
            SFormsFastMapDirect varmap = varmaparr[0];

            if (varassign != null)
            {
                int varindex = varassign.GetIndex();
                if (varassign.GetVersion() == 0)
                {
                    // get next version
                    int nextver = GetNextFreeVersion(varindex);
                    // set version
                    varassign.SetVersion(nextver);
                    SetCurrentVar(varmap, varindex, nextver);
                }
                else
                {
                    SetCurrentVar(varmap, varindex, varassign.GetVersion());
                }
            }
            else if (expr.type == Exprent.Exprent_Var)
            {
                VarExprent vardest  = (VarExprent)expr;
                int        varindex = vardest.GetIndex();
                FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex);
                int cardinality = vers.GetCardinality();
                if (cardinality == 1)
                {
                    // == 1
                    // set version
                    int it = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next();
                    vardest.SetVersion(it);
                }
                else if (cardinality == 2)
                {
                    // size > 1
                    int            current_vers = vardest.GetVersion();
                    VarVersionPair currpaar     = new VarVersionPair(varindex, current_vers);
                    if (current_vers != 0 && phi.ContainsKey(currpaar))
                    {
                        SetCurrentVar(varmap, varindex, current_vers);
                        // update phi node
                        phi.GetOrNull(currpaar).Union(vers);
                    }
                    else
                    {
                        // increase version
                        int nextver = GetNextFreeVersion(varindex);
                        // set version
                        vardest.SetVersion(nextver);
                        SetCurrentVar(varmap, varindex, nextver);
                        // create new phi node
                        Sharpen.Collections.Put(phi, new VarVersionPair(varindex, nextver), vers);
                    }
                }
            }
        }
예제 #4
0
        private void SetNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph,
                                      VarVersionsProcessor previousVersionsProcessor)
        {
            Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes
                                                                          ();
            Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes
                                                                          ();
            Dictionary <VarVersionPair, int> mapFinalVars = typeProcessor.GetMapFinalVars();
            CounterContainer counters = DecompilerContext.GetCounterContainer();
            Dictionary <VarVersionPair, int> mapVarPaar = new Dictionary <VarVersionPair, int>
                                                              ();
            Dictionary <int, int> mapOriginalVarIndices = new Dictionary <int, int>();

            // map var-version pairs on new var indexes
            foreach (VarVersionPair pair in new List <VarVersionPair>(mapExprentMinTypes.Keys))
            {
                if (pair.version >= 0)
                {
                    int newIndex = pair.version == 1 ? pair.var : counters.GetCounterAndIncrement(CounterContainer
                                                                                                  .Var_Counter);
                    VarVersionPair newVar = new VarVersionPair(newIndex, 0);
                    Sharpen.Collections.Put(mapExprentMinTypes, newVar, mapExprentMinTypes.GetOrNull(
                                                pair));
                    Sharpen.Collections.Put(mapExprentMaxTypes, newVar, mapExprentMaxTypes.GetOrNull(
                                                pair));
                    if (mapFinalVars.ContainsKey(pair))
                    {
                        Sharpen.Collections.Put(mapFinalVars, newVar, Sharpen.Collections.Remove(mapFinalVars
                                                                                                 , pair));
                    }
                    Sharpen.Collections.Put(mapVarPaar, pair, newIndex);
                    Sharpen.Collections.Put(mapOriginalVarIndices, newIndex, pair.var);
                }
            }
            // set new vars
            graph.IterateExprents((Exprent exprent) => {
                List <Exprent> lst = exprent.GetAllExprents(true);
                lst.Add(exprent);
                foreach (Exprent expr in lst)
                {
                    if (expr.type == Exprent.Exprent_Var)
                    {
                        VarExprent newVar = (VarExprent)expr;
                        int?newVarIndex   = mapVarPaar.GetOrNullable(new VarVersionPair(newVar));
                        if (newVarIndex != null)
                        {
                            newVar.SetIndex(newVarIndex.Value);
                            newVar.SetVersion(0);
                        }
                    }
                    else if (expr.type == Exprent.Exprent_Const)
                    {
                        VarType maxType = mapExprentMaxTypes.GetOrNull(new VarVersionPair(expr.id, -1));
                        if (maxType != null && maxType.Equals(VarType.Vartype_Char))
                        {
                            ((ConstExprent)expr).SetConstType(maxType);
                        }
                    }
                }
                return(0);
            }
                                  );
            if (previousVersionsProcessor != null)
            {
                Dictionary <int, int> oldIndices = previousVersionsProcessor.GetMapOriginalVarIndices
                                                       ();
                this.mapOriginalVarIndices = new Dictionary <int, int>(mapOriginalVarIndices.Count
                                                                       );
                foreach (KeyValuePair <int, int> entry in mapOriginalVarIndices)
                {
                    int value    = entry.Value;
                    int?oldValue = oldIndices.GetOrNullable(value);
                    value = oldValue != null ? oldValue.Value : value;
                    Sharpen.Collections.Put(this.mapOriginalVarIndices, entry.Key, value);
                }
            }
            else
            {
                this.mapOriginalVarIndices = mapOriginalVarIndices;
            }
        }